ChainSecurity performed a smart contract audit of Rarible’s staking contract, ERC721 token contract, and ERC1155 token contract.
ERC 721 and ERC1155
The ERC721 and ERC1155 contracts are build using OpenZeppelin’s upgradeable token templates. The following additional functionality was implemented:
- Multiple creators. A minted token is associated with one or multiple creators, namely the addresses that signed the minting data. Each creator of a token owns a share of it. The shares of a token need to add up to 10000, which represents 100% with 2 decimal places of precision.
- Mint and transfer. The function mintAndTransfer receives the minting data and signatures of creators, and then mints and transfers a token within the same contract call. The first creator of the token is the minter of the token. The mintAndTransfer function needs to be called by the minter or by a party approved by the minter.
- Default operators. The owner of the contract can assign the role of default operator. A default operator can transfer tokens of any user of the contract without prior approval from the user. The approval of a default operator cannot be revoked, and they can mintAndTransfer tokens on behalf of any minter.
There also a “User” version of the ERC721 and ERC1155 token contracts that does not have the “default operator” functionality. According to Rarible., these contracts are meant to be deployed using a proxy factory. They enable users to have their own contracts with the mintAndTransfer functionality. The minter of tokens on these contracts can only be the owner of the contract.
Staking contract allows users to lock ERC20 tokens for a period of time. The smallest unit of time that the contract tracks is one week. Each individual stake is identified by an ID and consists of 2 lines. The first
line is the lock line and it is defined by the following 3 parameters:
- Bias – the amount of tokens that the user locks inside the contract.
- Slope – the mount of tokens that are unlocked every week.
- Cliff – the period (in weeks), during which there is no unlocking.
The second line is the stake line, which equals the lock line scaled (multiplied) by a coefficient. That coefficient is computed based on cliff and slope period durations of the lock line. The longer any of the
two periods is, the greater the scaling coefficient will be. Each unique stake is associated with an owner and a delegate addresses. The delegate address is the address whose stake balance is increased by the
stake line of the given stake. The stake balance of the delegate address is the sum of all stake lines of all stakes that are delegated to it. The owner of a line can do following actions with the lock lines:
- Change the delegate of a stake line using the delagateTo function.
- Delete an existing lock line (identified by its ID), as well as update a lock line with a new bias and slope, provided that the bias is above the current locked amount and the new line terminates no earlier than the original line. That can be done by using restake function.
- Withdraw the already unlocked funds from all owned stakes.
The amount still locked is determined by the sum of all lock lines owned by address. The staking is assumed to be done with the Rari ERC20 token . The staking contract can be stopped by the contract’s owner. After stopping, no stakes can be created or changed. Users can withdraw all the tokens that they had in the contract. The contract’s owner can put the staking contract into a migration mode. In this mode stakes can be created and changed, but the user can also migrateTo specific ID stakes into a new contract.