Closed c4-bot-2 closed 10 months ago
alex-ppg marked the issue as duplicate of #152
alex-ppg marked the issue as insufficient quality report
Describes full balance transfer w/ max input relating to non-standard EIP-20 tokens for the FX portal, similar to how #152 describes deflationary / rebasing token incompatibility.
dmvt marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/governance/contracts/bridges/FxERC20ChildTunnel.sol#L96-L106 https://github.com/code-423n4/2023-12-autonolas/blob/2a095eb1f8359be349d23af67089795fb0be4ed1/governance/contracts/bridges/FxERC20RootTunnel.sol#L74-L77
Vulnerability details
Impact
if an erc20 token like
cUSDCV3
or with special behaviour similar tocUSDCV3
is added to theFxERC20ChildTunnel
bridge, it will be possible to trick the bridge to send a message toFxERC20RootTunnel
to mint max uint amount of bridged tokens to the user address. This behaviour happens because tokens likecUSDCV3
send the balance of the holder if the amount to be transferred is specified as type(uint).max instead of reverting. It is always best to check the balance of the user against the amount specified in parameter when intgerating erc20 tokens.Tokens like this,
cUSDCV3
for example have good representation on polygon and ethereum mainnet and tokens with these behaviour have been documented to exist - https://github.com/d-xo/weird-erc20?tab=readme-ov-file#transfer-of-less-than-amount It is better to designProof of Concept
https://github.com/compound-finance/comet/blob/22cf923b6263177555272dde8b0791703895517d/contracts/Comet.sol#L929
FxERC20ChildTunnel
, we can trick the FxERC20ChildTunnel to send a message to the FxERC20RootTunnel counterpart on L1 to mint max uint amount of tokens to the our address when we callFxERC20ChildTunnel.deposit()
.amount
is specified as max uint,_sendMessageToRoot()
is called, message is emitted andcUSDCV3.transferfrom()
is called.cUSDCV3.transferfrom()
is sucessful and the caller's totalcUSDCV3
balance is transferred to the bridge contract while_sendMessageToRoot()
emits a message with amount as max uint. Code snippet below.FxERC20ChildTunnel
on L2 is tricked and the message is sent,FxERC20RootTunnel.receiveMessage()
can be called. This will call_processMessageFromChild()
which will mint the max uint bridged ERC20 token amount to the user on L1. The bridgedERC20 tokens have no total supply specified so i expect it can be possible to mint up to max uint. Also this attack is very possible in the event where the FxERC20RootTunnel and its bridged ERC20 root token on L1 is newly launched, there will be zero supply at this point, a max uint value mint can be sucessfull and overflow error will be avoided. The attacker can try to be the first user and execute this attack from L2 to get a max uint bridged token balance on L1.I wrote a POC to illutrate this vuln.
/governance/test
folder and paste.governance
folder and runforge init --force
to initialise folder for forge testsgovernance
run run code with :forge test --mc BridgeTest -vvvvvv
Tools Used
MANUAL REVIEW, FOUNDRY
Recommended Mitigation Steps
FxERC20ChildTunnel.deposit()
like belowif user token balance is less than amount to be transferred, revert function.
Assessed type
ERC20