This assessment, like any RWA collateral type, deviates from the standard smart contract technical assessment format because of the idiosyncratic nature of the RWA collateral types.
For Centrifuge RWA collateral type, the DROP token of a Tinlake pool, FF1DRP in this case, is managed by MIP22 and interfaced with Maker Protocol through MIP21 and the creation of a placeholder token, by the deployment spell, RWA005 in this case.
For this assessment, we will be focusing on the MIP21 token RWA005 (to be deployed) for Fortunafi Series 1 FF1DRP token, as well as the infrastructure for all centrifuge tokens.
- Symbol: RWA005
- Relevant MIP information:
- Total supply: 1 WAD (1 * 10 ^ 18)
- Github repository:
Can use existing MCD collateral type adapter?
- This collateral use the MIP21 authed join and exit functions. These functions are similar to other RWA onboarding that uses this framework.
- Does the contract implement the ERC20 token standards? Yes.
- Decimals: 18.
- Overflow checks: No.
- Mitigation against allowance race-condition: No.
- Upgradeable contract patterns: No.
- Access control or restriction lists: No.
- Non-standard features or behaviors: No.
authgovernance address for
operatoraddress that is permitted to operate on the
RwaUrncontracts. This can be multiple addresses, however, each address must be approved by governance.
- The RWA code implementation resides within a sandbox-like environment, and any operation not related to locking, freeing, drawing, or wiping in the RwaUrn contract must be voted on by governance. The code itself is lightweight. This implementation uses simplified Oracle, and Urn contracts to achieve the functionality required for this specific instance of RWA.
- While there are no overflow checks, no use of a SafeMath library, and no mitigation against the allowance race-condition, the idiosyncratic nature of the contract does not make them a requirement.
The overall architecture is an integration between a Tinlake pool and Maker Protocol by using first MIP22 to manage the Tinlake DROP token (FF1DRP) then using MIP21 to handle a placeholder token (RWA005) and interact with Maker.
While MIP22/FF1DRP is discussed for the sake of comprehension, only the MIP21/RWA005 is considered for the scope of this assessment.
The implementation of MIP22 cand be find in the tinlake-maker-lib Github repo. The main contract is
The state diagram below shows the different stage of the smart contract and the transitions between them. It is important to note that there is no way to go back to an active state when a liquidation is started.
MIP22 operator is the MKR adapter on Tinlake called the clerk. It will use the
mat defined in the ilk and
matBuffer (clerk parameter) to check how much DROP tokens should be send to MIP22 in order to mint DAI.
MIP21 is the component that prevents the Tinlake pool from minting more than the Debt Ceiling (
line) and provides the ability for Maker Governance to trigger a liquidation. MIP21 by itself does not ensure that enough collateral (in the form of FF1DRP) is present.
The core RWA architecture consists of the following contracts:
RwaLiquidationOracle contract is shared across all MIP21 collateral types and consists of six state-changing functions (besides the usual DSS
deny(address)), all protected by the auth modifier and can only be called by governance:
init(bytes32 ilk,bytes32 val,address doc,uint48 tau)
bump(bytes32 ilk,uint256 val)
There is one externally accessible view function:
good(bytes32) that anyone can use to check the liquidation status of the position. This function does not change state.
This is not a typical Maker oracle. It will only report on the liquidation status of the
RwaUrn, and can only be acted upon by governance. To state it plainly, this oracle is not vulnerable to flash loan attacks or any manipulation aside from a governance attack.
file can be called by governance to change the
vow address (used in
init is the initialization function. It takes 4 parameters:
ilk: name of the vault, RWA005.
val: estimated value of the collateral. It should be above the Debt Ceiling (
line) and include a buffer for some accrued interest (e.g. 2 years of SF).
doc: link to legal documents representing the underlying legal scheme.
tau: minimum delay between the soft-liquidation and the hard-liquidation/write-off. If set to 0, this allows governance to trigger both in the same spell. For Centrifuge assets, this should be set to 0 (not impact outside of Maker anyway).
bump can be called by governance to increase (not decrease which can be done only by
cull) the estimated value of the collateral.
tell can be called by governance to start a soft-liquidation.
line should be set to 0 Dai first.
tell of MIP22
TinlakeManager should be called then (public function).
cure can be called by governance after a soft-liquidation has been triggered to stop it. It should not be used if
tell of MIP22
TinlakeManager was already called.
cull can be called by governance to start an hard-liquidation/write-off. This will mark all the remaining debt of the vault as bad debt and impact the Surplus Buffer (
cull of MIP22
TinlakeManager should be called then (public function).
RwaUrn is unique to each MIP21 collateral type. Aside from the core DSS
nope(address) functions, there are five functions:
file function can only be called by governance (via the
The rest of the functions can only be called by those who have been given permission (
noped) on the
RwaUrn contract. And any Dai drawn by the
RwaUrn can only be sent to the
outputConduit address defined by governance when deploying the contract.
A standard implementation of the ERC20 token standard, with the
balanceOf(address) of the deployer of the contract being set to
1 WAD at deployment. There is 18 decimals of precision.
There are three state changing functions, that are all available to the tokenholder, and are specific to the ERC20 token standard:
transfer(address dst, uint wad) external returns (bool);
transferFrom(address src, address dst, uint wad) public returns (bool);
approve(address usr, uint wad) external returns (bool);
To reiterate how simple this ERC20 token is, please reference the Surya Description Report section below and compare it against other ERC20 token assessments.
A simple contract with one function:
push() that can be called by anyone with a current
MKR balance. This function holds transitory funds, that upon being called, are transferred to the
to address set using the
pick function by those who have been given permission (hoped or noped).
An important note about the
RwaConduit for centrifuge assets. The contract above is not used, but rather the centrifuge manager contract acts as a compliant
RwaConduit. It is this manager that performs most of the functions of
MIP22 (mostly for liquidations), making centrifuge assets a MIP21/MIP22 hybrid design. That is, MIP21 leaves liquidations up to the structure of the RWA, and for centrifuge that structure is a slightly longer on-chain liquidation specific to the DROP token types.
The MIP21 construction contains low technical risk and is bounded by the debt ceiling. The PE core unit has given a reasonably deep review to the manager contract that acts as the
RwaConduit and resolved any issues there; however, only a surface review was given to the details of tinlake liquidations. This is where technical risk may exist. As of the time of this writing, this code has had a 120 people hour audit, and is currently undergoing more audits. Our team suggests a more conservative treatment of the debt ceiling to limit exposure to this unknown technical risk until more audits can be performed. This debt ceiling consideration should span across the aggregate of all collateral types using MIP22 until more audits are available.
The ERC20 functions of the
RwaToken are implemented to industry standard, but do not mitigate the allowance race-condition or use a SafeMath library. This is of minor consequence, as actual usage of the
approve(address,uint) function should be constrained. Future, more advanced implementations of RWA that will trade on markets should not use this implementation.
The core functions of the contracts are very limited in ability, and are restricted only to governance or the trusted addresses to lock, free, draw, or wipe Dai in the RwaUrn. Compared to a standard ERC20 token with administrative functions and multiple admin/controller addresses, this is a considerably lower risk contract.
The ERC20 token contract does not inherit other contracts.
|File Name||SHA-1 Hash|
|Function can modify state|
|Function is payable|