-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Unable to withdraw tokens from lockbox because the burn function will revert #742
Comments
It won't revert, because allowance is not checked: This is the call: XERC20.burn(msg.sender, _amount); So File: XERC20.sol
function burn(address _user, uint256 _amount) public virtual {
if (msg.sender != _user) {
_spendAllowance(_user, msg.sender, _amount);
}
_burnWithCaller(msg.sender, _user, _amount);
}
|
@howlbot reject |
The reasoning given by the validator is incorrect.
When the call is made from the Say, Alice wants to withdraw some of her tokens. Right now Alice is the File: XERC20LockBox.sol
function _withdraw(address _to, uint256 _amount) internal {
emit Withdraw(_to, _amount);
128: XERC20.burn(msg.sender, _amount);
... When the call is made from the File: XERC20.sol
function burn(address _user, uint256 _amount) public virtual {
if (msg.sender != _user) { ///note - XERC20LockBox contract is the msg.sender now. Not Alice
_spendAllowance(_user, msg.sender, _amount); /// note - will revert here
}
_burnWithCaller(msg.sender, _user, _amount);
} & because there has been no approval given by Alice to set an allowance to anyone, the function always calls Also the same situation described above would take would happen in the File: OptimismMintableXERC20.sol
68: function burn(address _from, uint256 _amount) public override(XERC20, IOptimismMintableERC20) {
69: XERC20.burn(_from, _amount);
70: } |
I agree that my comment could be misunderstood, so I will offer further explanation;
I was referring to this:
If you check the bridge calls, you will see that the https://github.com/search?q=repo%3Acode-423n4%2F2024-04-renzo+.burn%28&type=code In that case, the The other call (from XERC20LockBox) checks the allowance, but the user would simply approve it in a separate tx? I don't see why the contract should give allowance to itself when minting, the user can do it and then call burn. |
@DadeKuma Just like the sponsor said in the other reported issue,
This would work fine when the user is an EOA. But if the user is a smart contract who has already minted the tokens by depositing in the Lockbox, the user would not be able to burn the tokens because of missing approval & it would revert like explained above. Now if the is able user transfers those tokens to a different address & tries to burn with appropriate approvals, then it would still revert in the |
Yes, but that is the same impact as using |
If the user is a smart contract that can call |
Lines of code
https://github.com/code-423n4/2024-04-renzo/blob/main/contracts/Bridge/xERC20/contracts/XERC20.sol#L108-L109
Vulnerability details
mint()
&burn()
functions are used inside the XERC20 contract for bridges to mint & burn tokens for a user respectively.The issue arises while burning the tokens as they will always revert when
msg.sender != _user
due to insufficient allowance because the tokens were not approved while minting.Proof of Concept
The
_withdraw
function inside XERC20LockBox contract is used to withdraw tokens from the lockbox. It uses theburn
functionality of the XERC20 contract.The
burn
function is used for burning the tokens of a user. According to the check, when the caller is not the user, allowance is decreased by the given amount by calling the_spendAllowance()
.Here we can see the
currentAllowance
would be0
because it was not previously approved. Thus in the secondif
statementcurrentAllowance < value
will always be true & ultimately revert.Tools Used
Manual Review
Recommended Mitigation Steps
Maybe set an allowance while minting
Assessed type
Error
The text was updated successfully, but these errors were encountered: