General Information
This assessment deviates from the standard smart contract technical assessment format because of the idiosyncratic nature of the RWA collateral type. This assessment is intended only for the asset-backed lender scenario described in the Relevant MIP links section below, and should not be applied to other Real World Asset contracts.
In summary, because of their simplified and constrained nature, these contracts are considered low risk.
- Symbol: RWA-001
- Relevant MIP information:
- Total supply: 1 WAD (1 * 10 ^ 18)
- Github repository:
-
Can use existing MCD collateral type adapter?
- Yes, the AuthGemJoin adapter. You can find the actual implementation, slightly changed, here: https://github.com/livnev/rwa-example/blob/master/src/RwaJoin.sol
Technical Information
- 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.
-
Key addresses:
- The
auth
governance address - The
operator
address that is permitted to operate on theRwaUrn
contract. This can be multiple addresses, however, each address must be approved by governance.
- The
-
Additional notes:
- 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 Flipper, 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.
Reviewing the Architecture
The core RWA architecture consists of the following contracts:
- RwaLiquidationOracle
- RwaFlipper
- RwaUrn
- RwaToken
- RwaConduit
The following are considered out of scope for this assessment, and if needed, are subject to governance approval via an executive vote:
- RwaDeploySpell
- RwaInitSpell
- Auxiliary wallet contracts for handling disbursement and repayment of Dai
- RwaLiquidateSpell
- RwaRemedySpell
- RwaWriteOffSpell
RwaLiquidationOracle contract
Consists of four state-changing functions, all protected by the auth modifier and can only be called by governance:
-
init(bytes32,bytes32,address,uint48)
, -
tell(bytes32)
, -
cure(bytes32)
, -
cull(bytes32)
.
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.
RwaFlipper contract
Aside from the core DSS wards
, rely(address)
and deny(address)
functions, there is just one state-changing function and it is only callable by governance: kick(address,address,uint,uint,uint)
.
This Flipper contract does nothing but record the loss on the system’s balance sheet, allowing for system debt to be created.
RwaUrn
Aside from the core DSS wards
, can
, rely(address)
, deny(address)
, hope(address)
, and nope(address)
functions, there are five functions: file(bytes32,address)
, lock(uint256)
, free(uint256)
, draw(uint256)
, and wipte(uint256)
.
The file
function can only be called by governance (via the auth
modifier).
The rest of the functions can only by called by those who have been given permission (hoped
or noped
) on the RwaUrn
contract. And any Dai drawn by the RwaUrn
can only be sent to the fbo
address defined by governance when deploying the contract.
RwaToken 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 the ability of 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, please reference the Surya Description Report section below and compare it against other ERC20 token assessments.
RwaConduit
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 in the constructor when deploying the contract.
Contract Risk Summary
This is a low risk contract. 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.
Inheritance Diagram
The ERC20 token contract does not inherit other contracts.
Surya’s Description Report
Files Description Table
File Name | SHA-1 Hash |
---|---|
RwaToken.sol | 676984734384a844a7b9facf45cacfa8bebed9fa |
Contracts Description Table
Contract | Type | Bases | ||
---|---|---|---|---|
└ | Function Name | Visibility | Mutability | Modifiers |
RwaToken | Implementation | |||
└ | add | Internal ![]() |
||
└ | sub | Internal ![]() |
||
└ | Public ![]() |
![]() |
NO❗️ | |
└ | transfer | External ![]() |
![]() |
NO❗️ |
└ | transferFrom | Public ![]() |
![]() |
NO❗️ |
└ | approve | External ![]() |
![]() |
NO❗️ |
Legend
Symbol | Meaning |
---|---|
![]() |
Function can modify state |
![]() |
Function is payable |