USDG technical analysis
Summary
This is a technical analysis of all the smart contracts of the USDG asset and its main dependencies.
Disclosure: This is not an exhaustive security review of the asset like the ones done by Paxos, 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
The USDG token is a stablecoin regulated by the Monetary Authority of Singapore (MAS), issued by Paxos, and backed by USD held in segregated accounts. Customers who create a Paxos Institutional account and pass KYC requirements can mint and redeem 1:1 USDG in U.S. Dollars via the Paxos dashboard.
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 that can be considered important.
-
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 |
|---|---|
| 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. | |
| The role is controlled in a way that could expose the system and users to some risk depending on the actions it can control. | |
| The role is controlled via a clearly non-secure method, representing risks for the system and users. |
General points
-
USDG relies on two contracts with most dependencies from OZ for access control, tokenization, upgradability, and security. It uses the OZ UUPS Proxy pattern.
-
The system uses the role-based access control pattern for minting, burning tokens, and blocking addresses.
-
The system’s upgradeable admin and the owner of USDG are EOAs operated via MPC; further details on the MPC setup are provided below.
Contracts
The following is a non-exhaustive overview of the main smart contracts involved with USDG.
USDG
The USDG contract represents the Paxos stablecoin. It’s an upgradable UUPS Proxy that uses the PaxosTokenV2 standard, featuring pausability, and minting and burning controlled by a SupplyControl contract.
| USDG Permission Owner (Ethereum) | USDG Permission Owner (X Layer) | functions | Criticality | Risk (Ethereum) | Risk (X Layer) |
|---|---|---|---|---|---|
| upgradable admin: EOA* | upgradable admin: EOA* | upgradeTo, upgradeToAndCall | CRITICAL | ||
DEFAULT_ADMIN: EOA* |
DEFAULT_ADMIN: EOA* |
grantRole, reclaimToken, setSupplyControl | HIGH | ||
| allowed via SupplyControl: OFTWrapper, EOA, EOA* | allowed via SupplyControl: OFTWrapper | increaseSupplyToAddress, increaseSupply, mint, decreaseSupplyFromAddress, decreaseSupply, burn | HIGH | ||
ASSET_PROTECTION_ROLE: EOA* |
ASSET_PROTECTION_ROLE: EOA* |
wipeFrozenAddress, freeze, freezeBatch, unfreeze, unfreezeBatch | HIGH | ||
PAUSE_ROLE: EOA* |
PAUSE_ROLE: EOA* |
pause, unpause | HIGH |
*The EOAs refer to MPC wallets using internal infrastructure to secure private keys.
- Access Control
DEFAULT_ADMIN:-
can assign roles via the
grantRole(role, address)function. -
can set the SupplyControl via
setSupplyControl(address)function and recover USDG tokens sent to the USDG contract through thereclaimToken()function.
-
ASSET_PROTECTION_ROLE:-
can freeze and unfreeze users via the
freeze(address)unfreeze(address)methods. -
The tokens of freeze accounts can be burned via the
wipeFrozenAddress(address)function. -
Multiple addresses can be frozen and unfrozen via the
freezeBatch(address[])andunfreezeBatch(address[[])functions.
-
PAUSE_ROLE:- can pause and unpause mints, burns, and transfers via the
pause()andunpause()functions.
- can pause and unpause mints, burns, and transfers via the
- Minting and burn
-
Permissioned addresses via the Supply control can mint new USDG tokens by calling the
mint(to, amount)method or using the equivalentincreaseSupplyToAddress(amount, to),increaseSupply(amount)methods. -
Permissioned addresses via the Supply control can burn USDG tokens by calling the
burn(to, amount)method or using the equivalentdecreaseSupplyFromAddress(amount, to),decreaseSupply(amount)methods.
-
SupplyControl
The SupplyControl contract maintains a list of permissioned minters and burners of the USDG token, known as supplyControllers. SupplyControllers can optionally have rate limits to limit the number of tokens minted over a given time frame. It’s an upgradable UUPS Proxy that uses role-based access control.
| Permission Owner (Ethereum) | Permission Owner (X Layer) | functions | Criticality | Risk (Ethereum) | Risk (X Layer) |
|---|---|---|---|---|---|
| upgradable admin: EOA* | upgradable admin: EOA* | upgradeTo, upgradeToAndCall | CRITICAL | ||
DEFAULT_ADMIN: EOA* |
DEFAULT_ADMIN: EOA* |
grantRole | HIGH | ||
SUPPLY_CONTROLLER_MANAGER_ROLE: EOA* |
SUPPLY_CONTROLLER_MANAGER_ROLE: EOA* |
addSupplyController, removeSupplyController, updateLimitConfig, updateAllowAnyMintAndBurnAddress, addMintAddressToWhitelist, removeMintAddressFromWhitelist | HIGH | ||
SUPPLY_CONTROLLER_ROLE: OFTWrapper, EOA, EOA* |
SUPPLY_CONTROLLER_ROLE: OFTWrapper |
mint burn USDG | HIGH | ||
TOKEN_CONTRACT_ROLE : USDG |
TOKEN_CONTRACT_ROLE : USDG |
(view methods): canMintToAddress, canBurnFromAddress | HIGH |
*The EOAs refer to MPC wallets using internal infrastructure to secure private keys.
- Access Control
SUPPLY_CONTROLLER_MANAGER_ROLE:-
can add or remove SupplyControllers (USDG minter and burners) via the
addSupplyController(address supplyController, uint limitCapacity, uint refillPerSecond, address[] mintAddressWhitelist, bool allowAnyMintAndBurnAddress), andremoveSupplyController(address). ThemintAddressWhitelistaddresses are the ones allowed to receive fresh USDG tokens from thesupplyController. ThesupplyControlleraddress receives aSUPPLY_CONTROLLER_ROLE. -
The rate limits of supplyControllers can be configured via the
updateLimitConfig(address supplyController, uint limitCapacity, uint refillPerSecond)function. -
can allow SupplyControllers to mint and burn to and from any address via the
updateAllowAnyMintAndBurnAddress(address supplyController, bool allowAnyMintAndBurnAddress). -
can add or remove addresses from a SupplyController whitelist via the
addMintAddressToWhitelist(address supplyController, address account)andremoveMintAddressFromWhitelist(address supplyController, address account)functions.
-
PAUSE_ROLE:- can pause and unpause mints, burns, and transfers via the
pause()andunpause()functions.
- can pause and unpause mints, burns, and transfers via the
OFTWrapper
The OFTWrapper contract is an OFT Adapter extension contract that implements the OFT mechanisms, minting and burning tokens as they are bridged through LayerZero. It’s a non-upgradable contract.
| OFTWrapper Permission Owner (Ethereum) | OFTWrapper Permission Owner (X Layer) | functions | Criticality | Risk (Ethereum) | Risk (X Layer) |
|---|---|---|---|---|---|
| ownable: EOA* | ownable: EOA* | setPeer, setEnforcedOptions, setDelegate, setRateLimits, setMsgInspector | HIGH |
*The EOAs refer to MPC wallets using internal infrastructure to secure private keys.
- Bridge Mechanism
- Users send the USDG to the OFTWrapper adapter via the
send()function, which burns the tokens. Internally, the LZ endpoint contract is called to send a cross-chain message. On the destination chain, the KZ endpoint receives the message and calls thelzReceive()function in the respective OFTWrapper, which mints the USDG to the user.
- Users send the USDG to the OFTWrapper adapter via the
Pricing strategy
Since USDG will initially be available only as a borrowable asset, we have two options: either using a fixed 1 USD price feed or employing a CAPO stable adapter with the USDG/USD Chainlink Price Feed from the secondary market.
Using the secondary market feed is the preferred option if liquidity requirements allow, but given the intended configuration (borrowable-only) and that the secondary market can introduce price volatility that does not reflect the asset’s true value, the static price feed is acceptable.
Miscellaneous
-
Paxos uses attestations from a third-party accounting firm as PoR in accordance with standards established by the Institute of Singapore Chartered Accountants (“ISCA”). The attestations can be found here.
-
According to details shared by the Paxos team, we think their MPC setup is solid, using industry-standard infrastructure and both manual and automated policies.
-
Audits were performed by Halborn, Zellic, and Trail of Bits. They can be found here.
-
We proposed introducing timelocks for critical flows to the Paxos team, and they confirmed they plan to implement them in the near future.
Conclusion
We believe USDG has no issues with Aave integration as a borrow-only asset and see no major blockers to its listing. However, we consider a strict requirement to timelock critical flows before any future collateral usage is considered, and the pricing algorithm should be re-evaluated as part of that assessment.

