-
Notifications
You must be signed in to change notification settings - Fork 15
fix: Asynchronous burn reentrancy bug #17
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
base: main
Are you sure you want to change the base?
Conversation
|
Opening for discussion, currently untested. |
| function transfer(address to, euint64 value) public virtual returns (bool) { | ||
| require(TFHE.isSenderAllowed(value)); | ||
| address owner = _msgSender(); | ||
| ebool isTransferable = TFHE.le(value, _balances[msg.sender]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did not like this essential, universal check being the responsibility of the caller, so it is moved to _transfer and the logic is centralised in _hasSufficientBalance which also considers the _lockedBalances
| address account = burnRequest.account; | ||
| uint64 amount = burnRequest.amount; | ||
| if (!decryptedInput) { | ||
| revert("Decryption failed"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was a bit of a misleading error message
|
|
||
| ebool allowedTransfer = TFHE.le(amount, currentAllowance); | ||
|
|
||
| ebool canTransfer = TFHE.le(amount, _balances[owner]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
_transfer now handles the balance check
Original report: >>>�Hello, I think there may be an issue with the ConfidentialERC20Wrapper (https://github.com/Inco-fhevm/confidential-erc20-framework/blob/main/contracts/ConfidentialERC20Wrapper.sol).It seems possible to transfer funds while the Gateway is pending decryption (https://github.com/Inco-fhevm/confidential-erc20-framework/blob/main/contracts/ConfidentialERC20/ConfidentialERC20.sol#L247). Since the underflow is checked only when the unwrap function is called, it would be possible to steal all the ERC20 wrapped in the contract.For instance, let's say my encrypted balance is equal to 1. I call the unwrap() function with amount=1. Before the Gateway decrypts (and calls the callback function _burnCallback), I transfer my 1 to another address. Once the gateway calls the fallback, it would make my balance equal to type(uint64).max . Then, I can check the (decrypted) totalSupply and call another unwrap() passing amount = totalSupply . Once the gateway calls the callback (_burnCallback), it would transfer all the tokens to me Signed-off-by: Silas Davis <[email protected]>
e97c8ea to
26300f4
Compare
always freed Signed-off-by: Silas Davis <[email protected]>
Signed-off-by: Silas Davis <[email protected]>
|
|
||
| error BurnRequestDoesNotExist(uint256 requestId); | ||
|
|
||
| function _cancelBurn(uint256 requestId) internal virtual { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This could be exposed to the original sender/unwrapper if they wanted to cancel in-flight. We ought to be able to rely on the callback being called though, so we shouldn't need this just for cleaning up in-flight burns.
The EOA cna use the BurnRequested event to keep track of this requestId so it's possible to give them cancellation
|
If the request fails, the user will cancel it and retry? |
|
The issue with the requestBurn function is that it updates the locked balance before verifying the user has sufficient balance, causing a failure in every case. This violates the checks-effects-interactions principle. Link to relevant code - requestBurn |
Signed-off-by: Silas Davis <[email protected]>
9219c5c to
93c598e
Compare
Original report: