Skip to content

Commit

Permalink
fix: potential second minter blocks burnLockedUSDC (#93)
Browse files Browse the repository at this point in the history
# 🤖 Linear

Closes OPT-XXX
  • Loading branch information
excaliborr authored Jul 3, 2024
1 parent 207fd37 commit e20a7d8
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 2 deletions.
10 changes: 9 additions & 1 deletion src/contracts/L1OpUSDCBridgeAdapter.sol
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,15 @@ contract L1OpUSDCBridgeAdapter is IL1OpUSDCBridgeAdapter, OpUSDCBridgeAdapter {

// Burn the USDC tokens
if (burnAmount != 0) {
IUSDC(USDC).burn(burnAmount);
// NOTE: This is a very edge case and will only happen if the chain operator adds a second minter on L2
// So now this adapter doesnt have the full backing supply locked in this contract
// Incase the bridged usdc token has other minters and the supply sent is greater then what we have
// We need to burn the full amount stored in this contract
// This could also cause in-flight messages to fail because of the multiple supply sources
uint256 _balanceOf = IUSDC(USDC).balanceOf(address(this));
uint256 _burnAmount = burnAmount > _balanceOf ? _balanceOf : burnAmount;

IUSDC(USDC).burn(_burnAmount);

// Set the burn amount to 0
burnAmount = 0;
Expand Down
2 changes: 1 addition & 1 deletion src/interfaces/IL1OpUSDCFactory.sol
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ interface IL1OpUSDCFactory {
function deploy(
address _l1Messenger,
address _l1AdapterOwner,
L2Deployments memory _l2Deployments
L2Deployments calldata _l2Deployments
) external returns (address _l1Adapter, address _l2Factory, address _l2Adapter);

/*///////////////////////////////////////////////////////////////
Expand Down
26 changes: 26 additions & 0 deletions test/unit/L1OpUSDCBridgeAdapter.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ contract L1OpUSDCBridgeAdapter_Unit_BurnLockedUSDC is Base {
vm.assume(_burnAmount > 0);

_mockAndExpect(_usdc, abi.encodeWithSignature('burn(uint256)', _burnAmount), abi.encode(true));
_mockAndExpect(_usdc, abi.encodeWithSignature('balanceOf(address)', address(adapter)), abi.encode(_burnAmount));

adapter.forTest_setBurnAmount(_burnAmount);

Expand All @@ -416,6 +417,30 @@ contract L1OpUSDCBridgeAdapter_Unit_BurnLockedUSDC is Base {
vm.mockCall(
_usdc, abi.encodeWithSignature('burn(address,uint256)', address(adapter), _burnAmount), abi.encode(true)
);
vm.mockCall(_usdc, abi.encodeWithSignature('balanceOf(address)', address(adapter)), abi.encode(_burnAmount));

adapter.forTest_setBurnAmount(_burnAmount);

// Execute
vm.prank(_circle);
adapter.burnLockedUSDC();

assertEq(adapter.burnAmount(), 0, 'Burn amount should be set to 0');
assertEq(adapter.burnCaller(), address(0), 'Circle should be set to 0');
}

/**
* @notice Check that balance of gets used if burn amount is greater then the balance
*/
function test_balanceOfUsedIfBurnAmountGt(uint256 _burnAmount, uint256 _balanceOf, address _circle) external {
vm.assume(_burnAmount > 0);
vm.assume(_burnAmount > _balanceOf);
adapter.forTest_setBurnCaller(_circle);
adapter.forTest_setMessengerStatus(IL1OpUSDCBridgeAdapter.Status.Deprecated);

// solhint-disable-next-line max-line-length
vm.mockCall(_usdc, abi.encodeWithSignature('burn(address,uint256)', address(adapter), _balanceOf), abi.encode(true));
vm.mockCall(_usdc, abi.encodeWithSignature('balanceOf(address)', address(adapter)), abi.encode(_balanceOf));

adapter.forTest_setBurnAmount(_burnAmount);

Expand All @@ -436,6 +461,7 @@ contract L1OpUSDCBridgeAdapter_Unit_BurnLockedUSDC is Base {
adapter.forTest_setMessengerStatus(IL1OpUSDCBridgeAdapter.Status.Deprecated);

vm.mockCall(_usdc, abi.encodeWithSignature('burn(address)', address(adapter)), abi.encode(true));
vm.mockCall(_usdc, abi.encodeWithSignature('balanceOf(address)', address(adapter)), abi.encode(_burnAmount));

adapter.forTest_setBurnAmount(_burnAmount);

Expand Down

0 comments on commit e20a7d8

Please sign in to comment.