Skip to content

Commit

Permalink
BLOCKCHAIN-234 - bridge contracts - cap the supply limit that can be …
Browse files Browse the repository at this point in the history
…set by admin
  • Loading branch information
kacperzuk-neti committed Oct 19, 2023
1 parent e2efbc8 commit 46cad1b
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 29 deletions.
10 changes: 6 additions & 4 deletions eth-bridge/contracts/script/Deploy.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,9 @@ contract Deploy is Script {
fee,
30_000_000_000_000_000, // max burst mint
60_000_000_000_000, // rate limit counter decay
300_000_000_000_000_000, // max total supply
30_000_000_000_000 // min transfer
300_000_000_000_000_000, // supply limit
30_000_000_000_000, // min transfer
3_000_000_000_000_000_000 // max supply limit
)
)
);
Expand All @@ -67,8 +68,9 @@ contract Deploy is Script {
fee,
10_000_000_000_000_000, // max burst mint
20_000_000_000_000, // rate limit counter decay
100_000_000_000_000_000, // max total supply
10_000_000_000_000 // min transfer
100_000_000_000_000_000, // supply limit
10_000_000_000_000, // min transfer
1_000_000_000_000_000_000 // max supply limit
)
)
);
Expand Down
30 changes: 30 additions & 0 deletions eth-bridge/contracts/script/UpgradeBridgesToV2.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.18;

import "forge-std/Script.sol";
import "../src/Bridge.sol";

contract UpgradeBridgesToV2 is Script {
function run() external {
vm.startBroadcast();
Bridge lldProxy = Bridge(vm.envAddress("LLDBridgeProxy"));
Bridge llmProxy = Bridge(vm.envAddress("LLMBridgeProxy"));

Bridge newBridgeImpl = new Bridge();

lldProxy.upgradeToAndCall(
address(newBridgeImpl),
abi.encodeCall(
Bridge.initializeV2,
(3_000_000_000_000_000_000) // max supply limit of 3M LLD, admin can lower it
)
);
llmProxy.upgradeToAndCall(
address(newBridgeImpl),
abi.encodeCall(
Bridge.initializeV2,
(1_000_000_000_000_000_000) // max supply limit of 1M LLM, admin can lower it
)
);
}
}
30 changes: 29 additions & 1 deletion eth-bridge/contracts/src/Bridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ contract Bridge is Initializable, AccessControlUpgradeable, UUPSUpgradeable, Bri
RateLimitParameters public rateLimit; // 2x uint256
/// Minimum transfer - only applied for burns
uint256 public minTransfer;
/// Initial supply limit - admin can't increase supply limit above this value
uint256 public maxSupplyLimit;

constructor() {
_disableInitializers();
Expand All @@ -108,7 +110,23 @@ contract Bridge is Initializable, AccessControlUpgradeable, UUPSUpgradeable, Bri
/// @param decayRate initial `rateLimit.decayRate`
/// @param supplyLimit_ initial `supplyLimit`
/// @param minTransfer_ initial `minTransfer`
/// @param maxSupplyLimit_ maximum `supplyLimit` that can be set by admin
function initialize(
WrappedToken token_,
uint32 votesRequired_,
uint256 mintDelay_,
uint256 fee_,
uint256 counterLimit,
uint256 decayRate,
uint256 supplyLimit_,
uint256 minTransfer_,
uint256 maxSupplyLimit_
) external {
initializeV1(token_, votesRequired_, mintDelay_, fee_, counterLimit, decayRate, supplyLimit_, minTransfer_);
initializeV2(maxSupplyLimit_);
}

function initializeV1(
WrappedToken token_,
uint32 votesRequired_,
uint256 mintDelay_,
Expand All @@ -117,7 +135,7 @@ contract Bridge is Initializable, AccessControlUpgradeable, UUPSUpgradeable, Bri
uint256 decayRate,
uint256 supplyLimit_,
uint256 minTransfer_
) public initializer {
) internal initializer {
__AccessControl_init();
__UUPSUpgradeable_init();

Expand All @@ -134,6 +152,12 @@ contract Bridge is Initializable, AccessControlUpgradeable, UUPSUpgradeable, Bri
_grantRole(SUPER_ADMIN_ROLE, msg.sender);
}

/// Reinitializer from v1 to v2. Should be used in the same tx as upgrade
/// @param maxSupplyLimit_ maximum `supplyLimit` that can be set by admin
function initializeV2(uint256 maxSupplyLimit_) public reinitializer(2) {
maxSupplyLimit = maxSupplyLimit_;
}

/// Adding special users. See role docs on info who can grant each role
/// @param role Role to grant
/// @param account Account to grant the role to
Expand Down Expand Up @@ -361,7 +385,11 @@ contract Bridge is Initializable, AccessControlUpgradeable, UUPSUpgradeable, Bri
/// Set max circulating token supply
/// @param supplyLimit_ new supply limit
/// @dev Only addresses with SUPER_ADMIN_ROLE can call this
/// @dev Reverts with `InvalidArgument` if `supplyLimit_` is greater than original limit set in constructor
function setSupplyLimit(uint256 supplyLimit_) public onlyRole(SUPER_ADMIN_ROLE) {
if (supplyLimit_ > maxSupplyLimit) {
revert InvalidArgument();
}
supplyLimit = supplyLimit_;
}

Expand Down
39 changes: 17 additions & 22 deletions eth-bridge/contracts/test/Bridge.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,30 +30,19 @@ contract BridgeTest is Test, BridgeEvents {
token = WrappedToken(
address(
new ERC1967Proxy(
address(tokenImpl),
abi.encodeCall(
WrappedToken.initialize,
("Liberland Merits", "LLM")
)
address(tokenImpl),
abi.encodeCall(WrappedToken.initialize, ("Liberland Merits", "LLM"))
)
)
);

bridge = Bridge(
address(
new ERC1967Proxy(
address(bridgeImpl),
abi.encodeCall(
Bridge.initialize,
(
token,
2,
10,
4,
1000,
10,
650,
0
)
(token, 2, 10, 4, 1000, 10, 1_000_000, 0, 1_000_000)
)
)
)
Expand Down Expand Up @@ -269,6 +258,8 @@ contract BridgeTest is Test, BridgeEvents {
}

function testMintRespectsMaxIssuanceLimit() public {
// we start with 500 already minted
bridge.setSupplyLimit(650);
vm.startPrank(alice);
bridge.voteMint(receipt1, 1, 149, alice);
bridge.voteMint(receipt2, 1, 2, alice);
Expand Down Expand Up @@ -651,7 +642,6 @@ contract BridgeTest is Test, BridgeEvents {
}

function testRateLimitAllowsSingleTxAtLimit() public {
bridge.setSupplyLimit(99999);
vm.prank(bob);
bridge.voteMint(receipt1, 1, 1000, alice);
vm.startPrank(alice);
Expand All @@ -662,7 +652,6 @@ contract BridgeTest is Test, BridgeEvents {
}

function testRateLimitAllowsMultiTxAtLimit() public {
bridge.setSupplyLimit(99999);
vm.startPrank(bob);
bridge.voteMint(receipt1, 1, 500, alice);
bridge.voteMint(receipt2, 1, 500, alice);
Expand All @@ -678,7 +667,6 @@ contract BridgeTest is Test, BridgeEvents {
}

function testRateLimitAllowsUsingDecayedAmountRightAway() public {
bridge.setSupplyLimit(99999);
vm.startPrank(bob);
bridge.voteMint(receipt1, 1, 1000, alice);
bridge.voteMint(receipt2, 1, 10, alice);
Expand All @@ -695,7 +683,6 @@ contract BridgeTest is Test, BridgeEvents {
}

function testRateLimitGoesToZeroAfterWholeWindow() public {
bridge.setSupplyLimit(99999);
vm.startPrank(bob);
bridge.voteMint(receipt1, 1, 1000, alice);
bridge.voteMint(receipt2, 1, 1000, alice);
Expand All @@ -712,7 +699,6 @@ contract BridgeTest is Test, BridgeEvents {
}

function testRateLimitPreventsSingleBigMint() public {
bridge.setSupplyLimit(99999);
vm.prank(bob);
bridge.voteMint(receipt1, 1, 1001, alice);
vm.prank(alice);
Expand All @@ -724,7 +710,6 @@ contract BridgeTest is Test, BridgeEvents {
}

function testRateLimitPreventsMultiBigMint() public {
bridge.setSupplyLimit(99999);
vm.startPrank(bob);
bridge.voteMint(receipt1, 1, 501, alice);
bridge.voteMint(receipt2, 1, 500, alice);
Expand All @@ -742,7 +727,6 @@ contract BridgeTest is Test, BridgeEvents {
}

function testRateLimitRespectsDecay() public {
bridge.setSupplyLimit(99999);
vm.startPrank(bob);
bridge.voteMint(receipt1, 1, 1000, alice);
bridge.voteMint(receipt2, 1, 500, alice);
Expand Down Expand Up @@ -859,4 +843,15 @@ contract BridgeTest is Test, BridgeEvents {
bridge.setMinTransfer(9);
bridge.burn(9, substrate1);
}

function testSetSupplyLimitCantExceedMaxSupplyLimit() public {
uint256 maxLimit = bridge.maxSupplyLimit();

bridge.setSupplyLimit(maxLimit - 2);
bridge.setSupplyLimit(maxLimit - 1);
bridge.setSupplyLimit(maxLimit);

vm.expectRevert(InvalidArgument.selector);
bridge.setSupplyLimit(maxLimit + 1);
}
}
5 changes: 3 additions & 2 deletions eth-bridge/contracts/test/VoteFeeCompare.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import "../src/Bridge.sol";

using stdStorage for StdStorage;

contract BridgeTest is Test, BridgeEvents {
contract VoteFeeCompare is Test, BridgeEvents {
WrappedToken public token;
Bridge public bridge;

Expand Down Expand Up @@ -52,7 +52,8 @@ contract BridgeTest is Test, BridgeEvents {
1000,
10,
650,
0
0,
650
)
)
)
Expand Down

0 comments on commit 46cad1b

Please sign in to comment.