[ARFC] Onboard USDtb to Aave v3 Core Instance

USDtb (Ethereum) technical analysis

Summary


This is a technical analysis of all the smart contracts of the asset and main dependencies.

Disclosure: This is not an exhaustive security review of the asset like the ones done by the Ethena Labs, but an analysis from an Aave technical service provider on different aspects we consider critical to review before a new type of listing. Consequently, like with any security review, this is not an absolute statement that the asset is flawless, only that, in our opinion, we don’t see significant problems with its integration with Aave, apart from different trust points.



Analysis

USDtb is a stablecoin backed by institutional-grade tokenized U.S. treasury fund products, initially by BlackRock’s USD Institutional Digital Liquidity Fund Token.



Permissioned users can mint USDtb using other stablecoins, according to their minting agreements, using an RFC (Request for Quote) off-chain system for pricing. They can also redeem USDtb with little to no delays for other stablecoins or assets in the reserves. USDtb can also be acquired via secondary markets, such as CEXs or DEXs.

For the context of this analysis, our focus has been on the following aspects, critical for the correct and secure integration with Aave:

  • A recommendation of pricing strategy to be used in the integration asset <> Aave.
  • Any miscellaneous aspect of the code we can consider of importance.
  • Analysis of the access control (ownerships, admin roles) and the nature of the entities involved in the system. Regarding the table permissions’ holders and their criticality/risk, it is done following these guidelines:
Criticality Description
CRITICAL Usually super-admin functionality: it can compromise the system by completely changing its fundamentals, leading to loss of funds if misused or exploited. E.g. proxy admin, default admin
HIGH It can control several parts of the system with some risk of losing funds. E.g., general owners or admin roles involved in the flow of funds
MEDIUM It can cause malfunction and/or minor financial losses if misused or exploited. E.g., fee setter, fee recipient addresses
LOW It can cause system malfunctions but on non-critical parts without meaningful/direct financial losses. E.g., updating descriptions or certain non-critical parameters.
Risk Description
:green_circle: The role is controlled via a mechanism we consider safe, such as on-chain governance, a timelock contract, or setups involving multi-sigs under certain circumstances.
:yellow_circle: The role is controlled in a way that could expose the system and users to some risk depending on the actions it can control.
:red_circle: The role is controlled via a clearly non-secure method, representing risks for the system and users.


General points

  • The system has two contracts with most dependencies from OZ for access control, tokenization, upgradability and security.
  • For proxies, it uses the Transparent Proxy pattern. The upgradeability admin of the system is an 5-of-10 Safe Wallet.
  • The system uses a role-based access control, with defined entities in charge of minting, burning and redeeming, and freezing accounts.

Contracts

The following is a non-exhaustive overview of the main smart contracts involved with USDtb.


USDtb

The main contract of the system is an OZ upgradable ERC20 that represents the Ethena stablecoin. This contract presents features for minting and burning, different transfer states, white and black listing addresses, and redistribution of seized tokens from blacklisted addresses. It uses a role-based access control with a super admin that can upgrade and configure the contract.

Permission Owner functions Criticality Risk
upgradable admin: 5-of-10 Safe Wallet upgradeTo, upgradeToAndCall CRITICAL :yellow_circle:
owner and DEFAULT_ADMIN_ROLE: 5-of-10 Safe Wallet addMinter, removeMinter, redistributeLockedAmount, rescueTokens, updateTransferState CRITICAL :yellow_circle:
MINTER_CONTRACT: USDtbMinting mint HIGH :green_circle:
BLACKLIST_MANAGER_ROLE: not assigned addBlacklistAddress, removeBlacklistAddress HIGH :green_circle:
WHITELIST_MANAGER_ROLE: not assigned addWhitelistAddress, removeWhitelistAddress HIGH :green_circle:
BLACKLISTED_ROLE Blacklisted users receive this role - -
WHITELISTED_ROLE Whitelisted users receive this role - -
  • Access Control
    • The default admin can add and remove minters of USDtb via the addMinter(address) and removeMinter(address) function, which gives or removes the MINTER_CONTRACT role.
    • The default admin can burn the USDtb balance of a blacklisted user and mint it to a non-blacklisted address by calling the redistributeLockedAmount(from, to) function.
    • The default admin can change the transfer state (pause, unpause, and whitelist only) via the updateTransferState(state) function.
    • The BLACKLIST_MANAGER_ROLE can add or remove addresses from the blacklist via the addBlacklistAddress(address[]) and removeBlacklistAddress(address[]) functions, which grants or removes a BLACKLISTED_ROLE to the address
    • The WHITELIST_MANAGER_ROLE can add or remove addresses from the whitelist via the addWhitelistAddress(address[]) and removeWhitelistAddress(address[]) functions, which give or remove the WHITELISTED_ROLE role.
  • Minting and Transfers states
    • The MINTER_ROLE (assigned to the USDtbMinting contract) is responsible for minting new USDtb tokens via the mint(to, amount) function.
    • The contract has 3 different transfer states implemented in the _beforeTransfer() hook, which the admin can switch. The first state, FULLY_DISABLED, pauses all transfers across all addresses holding USDtb. The second state, WHITELIST_ENABLED, allows only addresses with the WHITELISTED_ROLE to send or receive USDtb. The last state is FULLY_ENABLED, which allows non-blacklisted addresses to send or receive USDtb.

USDtbMinting

The USDtbMinting is the contract to mint and redeem USDtb tokens directly. Entities that have undergone KYC requirements, called “benefactors,” can sign orders for minting and redeeming based on a price quote from an off-chain RFQ system. This contract also presents global and specific limits per block for minting and redemption depending on the collateral asset. It is a non-upgradable contract and uses role-based access control, where the super admin can configure those limits and add users and collateral assets.

Permission Owner functions Criticality Risk
owner and DEFAULT_ADMIN_ROLE: 5-of-10 Safe Wallet setGlobalMaxMintPerBlock, setGlobalMaxRedeemPerBlock, addSupportedAsset, removeSupportedAsset, addCustodianAddress, removeCustodianAddress, addWhitelistedBenefactor, removeWhitelistedBenefactor, setMaxMintPerBlock, setMaxRedeemPerBlock, setTokenType, setStablesDeltaLimit, setUSDtbToken HIGH :green_circle:
GATEKEEPER_ROLE disableMintRedeem, removeMinterRole, removeRedeemerRole,removeCollateralManagerRole HIGH :green_circle:
MINTER_ROLE mint HIGH :green_circle:
REDEEMER_ROLE redeem HIGH :green_circle:
COLLATERAL_MANAGER_ROLE transferToCustody HIGH :green_circle:
  • Access Control
    • The default admin can set global minting and redemption amounts of USDtb via the setGlobalMaxMintPerBlock(amount) and setGlobalMaxRedeemPerBlock(amount) functions, respectively. Those global amounts are currently set to 10,500,000/block for minting and 2,050,000/block for redemptions. The default admin can define asset-specific amounts via the setMaxMintPerBlock(amount, asset) and setMaxRedeemPerBlock(amount, asset) functions.
    • The default admin can onboard new assets as collateral of USDtb by calling the addSupportedAsset(address) function. The asset is configured with respective maximum mint and redemption amounts per block. The admin can also remove assets via the removeSupportedAsset(address) function, or change its type of STABLE or ASSET via the setTokenType(address, type) function.
    • Custodian wallets can be added or removed by the default admin via the addCustodianAddress(address) and removeCustodianAddress(address) functions, respectively. Custodians are those that can receive the collateral assets used to mint USDtb.
    • Benefactors are added or removed by the default admin via the addWhitelistedBenefactor(address) and removeWhitelistedBenefactor(address) functions. Benefactors can add beneficiaries by calling the setApprovedBeneficiary(address) function. Benefactors are users holding collateral assets for minting USDtb who have undergone KYC procedures, while beneficiaries are the addresses assigned to receive minted USDtb.
    • The default admin can set slippage restrictions to protect minting during price discrepancies via the setStablesDeltaLimit(bps).
    • The GATEKEEPER_ROLE can stop mints and redeems by calling the disableMintRedeem() function, which will set the global max mint and redeem variables to zero.
    • The GATEKEEPER_ROLE can remove the MINTER_ROLE, REDEEMER_ROLE, and COLLATERAL_MANAGER_ROLE roles from addresses by calling the removeMinterRole(address), removeRedeemerRole(address), and removeCollateralManagerRole(address) functions respectively.
    • The COLLATERAL_MANAGER_ROLE can send assets in the custody of the USDtbMinting contract via the transferToCustody(asset, to, amount) function. The to address needs to be an allowed custodian address.
  • Minting and Redemptions
    • To mint USDtb, first, the benefactor assigns an order off-chain containing the amount to mint and which collateral asset will be used. Then, the benefactor calls mint(order, route, signature), which internally verifies whether the signature is valid for the order, whether the order amount is within the collateral asset and global limits per block, and whether the route addresses are valid custodians. If everything meets the requirements, the collateral asset amount is transferred to the route addresses, and the USDtb is minted for the beneficiary.
    • Similar to the mint process, first, the benefactor needs to sign an off-chain redemption order with the amount to redeem and which asset to redeem. Then, it calls the redeem(order, signature) function, which validates that the signature corresponds to the referent order and whether the amount is within the asset and global limits for redemption. It finishes by burning the USDtb from the benefactor and transferring the collateral asset to the beneficiary.

Pricing strategy

We suggest pricing using the USDtb/USD Chainlink price feed through the CAPO’s stables adapter.

Miscellaneous

  • The system has security reviews by Cyfrin, Pashov, Quantstamp, and a public contest on Code4Arena. The reports can be found here.
  • With minting/redemption being a permissioned flow, it is important for risk contributors to analyse that this will not cause any problem in liquidation dynamics, for example, monitoring that LB of collaterals against USDtb is solid, or if applicable, Liquid eMode configurations.

Conclusion

We think USDtb doesn’t have any problem in terms of integration with Aave, and there is no major blocker.

Following our discussion with the Ethena Team during the analysis, we suggested time-locking the upgradable admin of USDTb for security reasons, for example, to give more time to validate the changes made in a new implementation. The team committed to improving this component.

However, we don’t think that is a blocker for listing, given the use case of the asset, and the security track record of Ethena.