Open franck44 opened 5 days ago
On L1: poolUnlocked is the difference between 10B (max supply) and current balance and poolLocked is the balance of bridgeInitiator Contract On L2: poolUnlocked is the current supply and poolLocked is the difference between 10B (max supply) and the current supply. Don't think adding more params helps us, we could these constants for extra care.
One issue I can foresee is if there's an exploit, using poolUnlocked and poolLocked will lead to bugs as invalid minting or removal of tokens would lead to an unbalance between the tokens.
note: poolBalance has already shown to bug and ERC20() _transfer already handles the logic it was meant to serve. removal of poolBalance has been merged into Solidity Bridge Deployment Scripts
One issue I can foresee is if there's an exploit, using poolUnlocked and poolLocked will lead to bugs as invalid minting or removal of tokens would lead to an unbalance between the tokens.
How can variables that are just updated but do not change the control flow create bugs?
The poolLocked
and poolUnlocked
are not related to minting (this is in the ERC-20).
This comment does not seem relevant here.
note: poolBalance has already shown to bug and ERC20() _transfer already handles the logic it was meant to serve. > removal of poolBalance has been merged into https://github.com/movementlabsxyz/movement/pull/681
How can a variable in a bridge contract "bug" another contract (an ERC-20)?
it bugs, it doesn't bug another contract, it's buggy by itself because we are not implementing a full logic and the full logic is simply implemented by ERC20. They are attempting to perform the same logic, but currently do not do so. It's redudant logic.
Problem
In the AtomicBridgeInitiatorMOVE.sol contract, the
poolBalance
variable that is supposed to track the current amount of locked tokens in the bridge is used in withdrawMOVEand can prevent a withdrawal (moveToken.transfer
).Here is the completeBridgeTransfer function in AtomicBridgeCounterpartyMOVE.sol:
This results in at least two issues:
poolBalance >= amount
may prevent use from fixing a compromised bridgewithdraw
inAtomicBridgeInitiatorMOVE.sol
is modified, this impacts the behaviour of the counter party.Possible changes
One thing that should probably be done is: remove the line
if (poolBalance < amount) revert InsufficientMOVEBalance();
in the AtomicBridgeInitiatorMOVE.sol contract as it does not serve any purpose and can be dangerous (Issue 1 above).Once this is done we have two options to address the cross-contract call:
poolBalance
and merge the code of the two contractspoolBalance
intopoolLocked
andpoolUnlocked
, withpoolLocked
(respectivelypoolUnlocked
) tracking what has been locked in the bridge (via initiateBridgeTransfer) andpoolUnlocked
tracking what has been unlocked from the bridge (via completeBridgeTransfer in AtomicBridgeCounterpartyMOVE.sol. Concretely, we removepoolBalance
and replace withpoolLocked
in AtomicBridgeInitiatorMOVE.sol and we addpoolUnlocked
in AtomicBridgeCounterpartyMOVE.sol.Option 1 has one advantage: it is easy to implement, but a serious drawback as we may not be able to track the bridge
poolBalance
(or anything related to how much went in and out the bridge).Option 2 above has two advantages:
poolBalance
can be reconstructed frompoolLocked - poolUnlocked
Initiator
(bridging L1 to L2) and theCounterParty
(bridging L2 to L1) indepedent as we can move thewithdraw
function out of AtomicBridgeInitiatorMOVE.sol into in completeBridgeTransfer (or inline it) in AtomicBridgeCounterpartyMOVE.sol.Implementation
One we have decided whether or not we want to fix issues 1 and 2, and which option is preferred, we can implement the changes. This requires:
poolLocked
andpoolUnlocked
in the two contractsIn practice, in AtomicBridgeInitiatorMOVE.sol, we rename
poolBalance
intopoolLocked
, and in AtomicBridgeCounterpartyMOVE.sol we add a variablepoolUnlocked
and modify the function completeBridgeTransfer to:Validation
We need to add some unit tests to test that:
poolLocked
andpoolUnlocked
variables are updated properly (and this for each function in each contract).