From decf8f495440c6524a8dd66bf226da5d04959740 Mon Sep 17 00:00:00 2001 From: maptuhec Date: Sat, 12 Mar 2022 12:40:00 +0200 Subject: [PATCH 1/3] add whitelist functionality --- solidity/contracts/Gravity.sol | 41 ++- solidity/test/submitBatch-vs-logicCall.ts | 353 ++++++++++++++++++++++ solidity/test/submitBatch.ts | 247 ++++++++++++++- solidity/test/updateValset.ts | 64 +++- 4 files changed, 697 insertions(+), 8 deletions(-) diff --git a/solidity/contracts/Gravity.sol b/solidity/contracts/Gravity.sol index cdabbe302..674c0e83e 100644 --- a/solidity/contracts/Gravity.sol +++ b/solidity/contracts/Gravity.sol @@ -62,6 +62,8 @@ contract Gravity is ReentrancyGuard { BridgeAccessControl public bridgeAccessControl; + mapping(address => bool) public whitelisted; + // TransactionBatchExecutedEvent and SendToCosmosEvent both include the field _eventNonce. // This is incremented every time one of these events is emitted. It is checked by the // Cosmos module to ensure that all events are received in order, and that none are lost. @@ -104,6 +106,35 @@ contract Gravity is ReentrancyGuard { uint256 _eventNonce ); + event WhitelistedStatusModified( + address _sender, + address[] _users, + bool _isWhitelisted + ); + + + modifier onlyWhitelisted() { + require( + whitelisted[msg.sender] || bridgeAccessControl.hasAdminRole(msg.sender) , + "The caller is not whitelisted for this operation" + ); + _; + } + + function manageWhitelist( + address[] memory _users, + bool _isWhitelisted + ) public onlyWhitelisted { + for (uint256 i = 0; i < _users.length; i++) { + require( + _users[i] != address(0), + "User is the zero address" + ); + whitelisted[_users[i]] = _isWhitelisted; + } + emit WhitelistedStatusModified(msg.sender, _users, _isWhitelisted); + } + // TEST FIXTURES // These are here to make it easier to measure gas usage. They should be removed before production function testMakeCheckpoint( @@ -233,7 +264,7 @@ contract Gravity is ReentrancyGuard { uint8[] memory _v, bytes32[] memory _r, bytes32[] memory _s - ) public { + ) public onlyWhitelisted { // CHECKS // Check that the valset nonce is greater than the old one @@ -301,7 +332,7 @@ contract Gravity is ReentrancyGuard { // to the destination addresses. It is approved by the current Cosmos validator set. // Anyone can call this function, but they must supply valid signatures of state_powerThreshold of the current valset over // the batch. - function submitBatch( + function submitBatch ( // The validators that approve the batch ValsetArgs memory _currentValset, // These are arrays of the parts of the validators signatures @@ -317,7 +348,7 @@ contract Gravity is ReentrancyGuard { // a block height beyond which this batch is not valid // used to provide a fee-free timeout uint256 _batchTimeout - ) public nonReentrant { + ) public nonReentrant onlyWhitelisted{ // CHECKS scoped to reduce stack depth { // Check that the batch nonce is higher than the last nonce for this token @@ -422,7 +453,7 @@ contract Gravity is ReentrancyGuard { bytes32[] memory _r, bytes32[] memory _s, LogicCallArgs memory _args - ) public nonReentrant { + ) public nonReentrant onlyWhitelisted { // CHECKS scoped to reduce stack depth { // Check that the call has not timed out @@ -534,7 +565,7 @@ contract Gravity is ReentrancyGuard { address _tokenContract, bytes32 _destination, uint256 _amount - ) public nonReentrant { + ) public nonReentrant { IERC20(_tokenContract).safeTransferFrom(msg.sender, address(this), _amount); state_lastEventNonce = state_lastEventNonce.add(1); emit SendToCosmosEvent( diff --git a/solidity/test/submitBatch-vs-logicCall.ts b/solidity/test/submitBatch-vs-logicCall.ts index b2b7cc032..d03c55582 100644 --- a/solidity/test/submitBatch-vs-logicCall.ts +++ b/solidity/test/submitBatch-vs-logicCall.ts @@ -373,3 +373,356 @@ describe("Compare gas usage of old submitBatch method vs new logicCall method su ).to.be.revertedWith("ReentrancyGuard: reentrant call"); }); }); + +describe("Testing whitelisting on logic call", function() { + it("Should not throw if the signer is whitelisted", async function() { + + let batchSize = 1 + let reentrant = false + + const { + signers, + gravityId, + powers, + validators, + gravity, + testERC20, + reentrantERC20, + } = await prep(); + + const TestTokenBatchMiddleware = await ethers.getContractFactory( + "TestTokenBatchMiddleware" + ); + const tokenBatchMiddleware = (await TestTokenBatchMiddleware.deploy()) as TestTokenBatchMiddleware; + await tokenBatchMiddleware.transferOwnership(gravity.address); + + // Lock tokens in gravity + // ==================== + await sendToCosmos(gravity, testERC20, 1000); + + expect( + (await testERC20.functions.balanceOf(gravity.address))[0].toNumber(), + "gravity does not have correct balance after sendToCosmos" + ).to.equal(1000); + + expect( + ( + await testERC20.functions.balanceOf(await signers[0].getAddress()) + )[0].toNumber(), + "msg.sender does not have correct balance after sendToCosmos" + ).to.equal(9000); + + // Preparing tx batch + // =================================== + const txBatch = await prepareTxBatch(batchSize, signers); + const batchNonce = 1; + + // Using logicCall method + // ======================== + const methodName = ethers.utils.formatBytes32String("logicCall"); + + let logicCallArgs = { + transferAmounts: [txBatch.numTxs], // transferAmounts + transferTokenContracts: [testERC20.address], // transferTokenContracts + feeAmounts: [txBatch.numTxs], // feeAmounts + feeTokenContracts: [testERC20.address], // feeTokenContracts + logicContractAddress: tokenBatchMiddleware.address, // logicContractAddress + payload: tokenBatchMiddleware.interface.encodeFunctionData("submitBatch", [ + txBatch.amounts, + txBatch.destinations, + reentrant ? reentrantERC20.address : testERC20.address, + ]), // payload + timeOut: 4766922941000, // timeOut, Far in the future + invalidationId: ethers.utils.hexZeroPad(testERC20.address, 32), // invalidationId + invalidationNonce: 1, // invalidationNonce + }; + + const digest = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + [ + "bytes32", // gravityId + "bytes32", // methodName + "uint256[]", // transferAmounts + "address[]", // transferTokenContracts + "uint256[]", // feeAmounts + "address[]", // feeTokenContracts + "address", // logicContractAddress + "bytes", // payload + "uint256", // timeOut + "bytes32", // invalidationId + "uint256", // invalidationNonce + ], + [ + gravityId, + methodName, + logicCallArgs.transferAmounts, + logicCallArgs.transferTokenContracts, + logicCallArgs.feeAmounts, + logicCallArgs.feeTokenContracts, + logicCallArgs.logicContractAddress, + logicCallArgs.payload, + logicCallArgs.timeOut, + logicCallArgs.invalidationId, + logicCallArgs.invalidationNonce, + ] + ) + ); + + const sigs = await signHash(validators, digest); + + let valset = { + validators: await getSignerAddresses(validators), + powers, + valsetNonce: 0, + rewardAmount: 0, + rewardToken: ZeroAddress + } + await gravity.manageWhitelist([signers[3].address], true) + + await gravity.connect(signers[3]).submitLogicCall( + valset, + + sigs.v, + sigs.r, + sigs.s, + logicCallArgs + ); + }) + + it("Should throw if the signer is not whitelisted", async function() { + + let batchSize = 1 + let reentrant = false + + const { + signers, + gravityId, + powers, + validators, + gravity, + testERC20, + reentrantERC20, + } = await prep(); + + const TestTokenBatchMiddleware = await ethers.getContractFactory( + "TestTokenBatchMiddleware" + ); + const tokenBatchMiddleware = (await TestTokenBatchMiddleware.deploy()) as TestTokenBatchMiddleware; + await tokenBatchMiddleware.transferOwnership(gravity.address); + + // Lock tokens in gravity + // ==================== + await sendToCosmos(gravity, testERC20, 1000); + + expect( + (await testERC20.functions.balanceOf(gravity.address))[0].toNumber(), + "gravity does not have correct balance after sendToCosmos" + ).to.equal(1000); + + expect( + ( + await testERC20.functions.balanceOf(await signers[0].getAddress()) + )[0].toNumber(), + "msg.sender does not have correct balance after sendToCosmos" + ).to.equal(9000); + + // Preparing tx batch + // =================================== + const txBatch = await prepareTxBatch(batchSize, signers); + const batchNonce = 1; + + // Using logicCall method + // ======================== + const methodName = ethers.utils.formatBytes32String("logicCall"); + + let logicCallArgs = { + transferAmounts: [txBatch.numTxs], // transferAmounts + transferTokenContracts: [testERC20.address], // transferTokenContracts + feeAmounts: [txBatch.numTxs], // feeAmounts + feeTokenContracts: [testERC20.address], // feeTokenContracts + logicContractAddress: tokenBatchMiddleware.address, // logicContractAddress + payload: tokenBatchMiddleware.interface.encodeFunctionData("submitBatch", [ + txBatch.amounts, + txBatch.destinations, + reentrant ? reentrantERC20.address : testERC20.address, + ]), // payload + timeOut: 4766922941000, // timeOut, Far in the future + invalidationId: ethers.utils.hexZeroPad(testERC20.address, 32), // invalidationId + invalidationNonce: 1, // invalidationNonce + }; + + const digest = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + [ + "bytes32", // gravityId + "bytes32", // methodName + "uint256[]", // transferAmounts + "address[]", // transferTokenContracts + "uint256[]", // feeAmounts + "address[]", // feeTokenContracts + "address", // logicContractAddress + "bytes", // payload + "uint256", // timeOut + "bytes32", // invalidationId + "uint256", // invalidationNonce + ], + [ + gravityId, + methodName, + logicCallArgs.transferAmounts, + logicCallArgs.transferTokenContracts, + logicCallArgs.feeAmounts, + logicCallArgs.feeTokenContracts, + logicCallArgs.logicContractAddress, + logicCallArgs.payload, + logicCallArgs.timeOut, + logicCallArgs.invalidationId, + logicCallArgs.invalidationNonce, + ] + ) + ); + + const sigs = await signHash(validators, digest); + + let valset = { + validators: await getSignerAddresses(validators), + powers, + valsetNonce: 0, + rewardAmount: 0, + rewardToken: ZeroAddress + } + + await expect( gravity.connect(signers[3]).submitLogicCall( + valset, + + sigs.v, + sigs.r, + sigs.s, + logicCallArgs + )).to.be.revertedWith("The caller is not whitelisted for this operation"); + }) + + it("Should throw if the signer is removed from the whitelist", async function() { + + let batchSize = 1 + let reentrant = false + + const { + signers, + gravityId, + powers, + validators, + gravity, + testERC20, + reentrantERC20, + } = await prep(); + + const TestTokenBatchMiddleware = await ethers.getContractFactory( + "TestTokenBatchMiddleware" + ); + const tokenBatchMiddleware = (await TestTokenBatchMiddleware.deploy()) as TestTokenBatchMiddleware; + await tokenBatchMiddleware.transferOwnership(gravity.address); + + // Lock tokens in gravity + // ==================== + await sendToCosmos(gravity, testERC20, 1000); + + expect( + (await testERC20.functions.balanceOf(gravity.address))[0].toNumber(), + "gravity does not have correct balance after sendToCosmos" + ).to.equal(1000); + + expect( + ( + await testERC20.functions.balanceOf(await signers[0].getAddress()) + )[0].toNumber(), + "msg.sender does not have correct balance after sendToCosmos" + ).to.equal(9000); + + // Preparing tx batch + // =================================== + const txBatch = await prepareTxBatch(batchSize, signers); + const batchNonce = 1; + + // Using logicCall method + // ======================== + const methodName = ethers.utils.formatBytes32String("logicCall"); + + let logicCallArgs = { + transferAmounts: [txBatch.numTxs], // transferAmounts + transferTokenContracts: [testERC20.address], // transferTokenContracts + feeAmounts: [txBatch.numTxs], // feeAmounts + feeTokenContracts: [testERC20.address], // feeTokenContracts + logicContractAddress: tokenBatchMiddleware.address, // logicContractAddress + payload: tokenBatchMiddleware.interface.encodeFunctionData("submitBatch", [ + txBatch.amounts, + txBatch.destinations, + reentrant ? reentrantERC20.address : testERC20.address, + ]), // payload + timeOut: 4766922941000, // timeOut, Far in the future + invalidationId: ethers.utils.hexZeroPad(testERC20.address, 32), // invalidationId + invalidationNonce: 1, // invalidationNonce + }; + + const digest = ethers.utils.keccak256( + ethers.utils.defaultAbiCoder.encode( + [ + "bytes32", // gravityId + "bytes32", // methodName + "uint256[]", // transferAmounts + "address[]", // transferTokenContracts + "uint256[]", // feeAmounts + "address[]", // feeTokenContracts + "address", // logicContractAddress + "bytes", // payload + "uint256", // timeOut + "bytes32", // invalidationId + "uint256", // invalidationNonce + ], + [ + gravityId, + methodName, + logicCallArgs.transferAmounts, + logicCallArgs.transferTokenContracts, + logicCallArgs.feeAmounts, + logicCallArgs.feeTokenContracts, + logicCallArgs.logicContractAddress, + logicCallArgs.payload, + logicCallArgs.timeOut, + logicCallArgs.invalidationId, + logicCallArgs.invalidationNonce, + ] + ) + ); + + const sigs = await signHash(validators, digest); + + let valset = { + validators: await getSignerAddresses(validators), + powers, + valsetNonce: 0, + rewardAmount: 0, + rewardToken: ZeroAddress + } + + await gravity.manageWhitelist([signers[3].address], true) + + await gravity.connect(signers[3]).submitLogicCall( + valset, + + sigs.v, + sigs.r, + sigs.s, + logicCallArgs + ); + await gravity.manageWhitelist([signers[3].address], false) + await expect( gravity.connect(signers[3]).submitLogicCall( + valset, + + sigs.v, + sigs.r, + sigs.s, + logicCallArgs + )).to.be.revertedWith("The caller is not whitelisted for this operation"); + }) +}) \ No newline at end of file diff --git a/solidity/test/submitBatch.ts b/solidity/test/submitBatch.ts index 3cdd23ce7..14246ab56 100644 --- a/solidity/test/submitBatch.ts +++ b/solidity/test/submitBatch.ts @@ -12,6 +12,7 @@ import { examplePowers, ZeroAddress, } from "../test-utils/pure"; +import { connect } from "node:http2"; chai.use(solidity); const { expect } = chai; @@ -30,6 +31,7 @@ async function runTest(opts: { barelyEnoughPower?: boolean; malformedCurrentValset?: boolean; batchTimeout?: boolean; + notWhiteListed?: boolean; }) { @@ -169,6 +171,24 @@ async function runTest(opts: { rewardToken: ZeroAddress } + if (opts.notWhiteListed) { + + await gravity.connect(signers[3]).submitBatch( + valset, + + sigs.v, + sigs.r, + sigs.s, + + txAmounts, + txDestinations, + txFees, + batchNonce, + testERC20.address, + batchTimeout + ); + } + let batchSubmitTx = await gravity.submitBatch( valset, @@ -224,6 +244,12 @@ describe("submitBatch tests", function () { ); }); + it("throws if the sender is not whitelisted", async function () { + await expect(runTest({ notWhiteListed: true })).to.be.revertedWith( + "The caller is not whitelisted for this operation" + ); + }); + it("allows zeroed sig", async function () { await runTest({ zeroedValidatorSig: true }); }); @@ -325,7 +351,6 @@ describe("submitBatch Go test hash", function () { rewardAmount: 0, rewardToken: ZeroAddress } - await gravity.submitBatch( valset, @@ -340,5 +365,223 @@ describe("submitBatch Go test hash", function () { testERC20.address, batchTimeout ); - }); +}); + +it("produces good hash with newly whitelisted address", async function () { + // Prep and deploy contract + // ======================== + const signers = await ethers.getSigners(); + const gravityId = ethers.utils.formatBytes32String("foo"); + const powers = [6667]; + const validators = signers.slice(0, powers.length); + const powerThreshold = 6666; + const { + gravity, + testERC20, + checkpoint: deployCheckpoint, + } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + + // Prepare batch + // =============================== + const txAmounts = [1]; + const txFees = [1]; + const txDestinations = await getSignerAddresses([signers[5]]); + const batchNonce = 1; + const batchTimeout = ethers.provider.blockNumber + 1000; + + // Transfer out to Cosmos, locking coins + // ===================================== + await testERC20.functions.approve(gravity.address, 1000); + await gravity.functions.sendToCosmos( + testERC20.address, + ethers.utils.formatBytes32String("myCosmosAddress"), + 1000 + ); + + // Call method + // =========== + const batchMethodName = ethers.utils.formatBytes32String( + "transactionBatch" + ); + const abiEncodedBatch = ethers.utils.defaultAbiCoder.encode( + [ + "bytes32", + "bytes32", + "uint256[]", + "address[]", + "uint256[]", + "uint256", + "address", + "uint256", + ], + [ + gravityId, + batchMethodName, + txAmounts, + txDestinations, + txFees, + batchNonce, + testERC20.address, + batchTimeout, + ] + ); + const batchDigest = ethers.utils.keccak256(abiEncodedBatch); + + // console.log("elements in batch digest:", { + // gravityId: gravityId, + // batchMethodName: batchMethodName, + // txAmounts: txAmounts, + // txDestinations: txDestinations, + // txFees: txFees, + // batchNonce: batchNonce, + // batchTimeout: batchTimeout, + // tokenContract: testERC20.address, + // }); + // console.log("abiEncodedBatch:", abiEncodedBatch); + // console.log("batchDigest:", batchDigest); + + const sigs = await signHash(validators, batchDigest); + const currentValsetNonce = 0; + + let valset = { + validators: await getSignerAddresses(validators), + powers, + valsetNonce: currentValsetNonce, + rewardAmount: 0, + rewardToken: ZeroAddress + } + await gravity.manageWhitelist([signers[3].address], true) + await gravity.connect(signers[3]).submitBatch( + valset, + + sigs.v, + sigs.r, + sigs.s, + + txAmounts, + txDestinations, + txFees, + batchNonce, + testERC20.address, + batchTimeout + ); +}); + +it("throws when an address is removed from the whitelist", async function () { + // Prep and deploy contract + // ======================== + const signers = await ethers.getSigners(); + const gravityId = ethers.utils.formatBytes32String("foo"); + const powers = [6667]; + const validators = signers.slice(0, powers.length); + const powerThreshold = 6666; + const { + gravity, + testERC20, + checkpoint: deployCheckpoint, + } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + + // Prepare batch + // =============================== + const txAmounts = [1]; + const txFees = [1]; + const txDestinations = await getSignerAddresses([signers[5]]); + const batchNonce = 1; + const batchTimeout = ethers.provider.blockNumber + 1000; + + // Transfer out to Cosmos, locking coins + // ===================================== + await testERC20.functions.approve(gravity.address, 1000); + await gravity.functions.sendToCosmos( + testERC20.address, + ethers.utils.formatBytes32String("myCosmosAddress"), + 1000 + ); + + // Call method + // =========== + const batchMethodName = ethers.utils.formatBytes32String( + "transactionBatch" + ); + const abiEncodedBatch = ethers.utils.defaultAbiCoder.encode( + [ + "bytes32", + "bytes32", + "uint256[]", + "address[]", + "uint256[]", + "uint256", + "address", + "uint256", + ], + [ + gravityId, + batchMethodName, + txAmounts, + txDestinations, + txFees, + batchNonce, + testERC20.address, + batchTimeout, + ] + ); + const batchDigest = ethers.utils.keccak256(abiEncodedBatch); + + // console.log("elements in batch digest:", { + // gravityId: gravityId, + // batchMethodName: batchMethodName, + // txAmounts: txAmounts, + // txDestinations: txDestinations, + // txFees: txFees, + // batchNonce: batchNonce, + // batchTimeout: batchTimeout, + // tokenContract: testERC20.address, + // }); + // console.log("abiEncodedBatch:", abiEncodedBatch); + // console.log("batchDigest:", batchDigest); + + const sigs = await signHash(validators, batchDigest); + const currentValsetNonce = 0; + + let valset = { + validators: await getSignerAddresses(validators), + powers, + valsetNonce: currentValsetNonce, + rewardAmount: 0, + rewardToken: ZeroAddress + } + await gravity.manageWhitelist([signers[3].address], true) + await gravity.connect(signers[3]).submitBatch( + valset, + + sigs.v, + sigs.r, + sigs.s, + + txAmounts, + txDestinations, + txFees, + batchNonce, + testERC20.address, + batchTimeout + ); + + await gravity.manageWhitelist([signers[3].address], false) + + await expect(gravity.connect(signers[3]).submitBatch( + valset, + + sigs.v, + sigs.r, + sigs.s, + + txAmounts, + txDestinations, + txFees, + batchNonce, + testERC20.address, + batchTimeout + )).to.be.revertedWith("The caller is not whitelisted for this operation") +}); + }); diff --git a/solidity/test/updateValset.ts b/solidity/test/updateValset.ts index 29f92f7f5..d93c6cb90 100644 --- a/solidity/test/updateValset.ts +++ b/solidity/test/updateValset.ts @@ -30,6 +30,9 @@ async function runTest(opts: { badReward?: boolean; notEnoughReward?: boolean; withReward?: boolean; + notWhiteListed?: boolean; + isWHitelisted?: boolean; + removedWhitelist:? boolean; }) { let bridgeAccessControl:any @@ -162,8 +165,52 @@ async function runTest(opts: { powers.pop(); } + if (opts.notWhiteListed) { + await gravity.connect(signers[3]).updateValset( + newValset, + currentValset, + sigs.v, + sigs.r, + sigs.s + ) + } + + let valsetUpdateTx + if (opts.isWHitelisted) { + await gravity.manageWhitelist([signers[3].address], true) + valsetUpdateTx = await gravity.connect(signers[3]).updateValset( + newValset, + currentValset, + sigs.v, + sigs.r, + sigs.s + ) + + return { gravity, checkpoint }; + } - let valsetUpdateTx = await gravity.updateValset( + if(opts.removedWhitelist) { + await gravity.manageWhitelist([signers[3].address], true) + valsetUpdateTx = await gravity.connect(signers[3]).updateValset( + newValset, + currentValset, + sigs.v, + sigs.r, + sigs.s + ) + + await gravity.manageWhitelist([signers[3].address], false) + valsetUpdateTx = await gravity.connect(signers[3]).updateValset( + newValset, + currentValset, + sigs.v, + sigs.r, + sigs.s + ) + } + + + valsetUpdateTx = await gravity.updateValset( newValset, currentValset, sigs.v, @@ -241,6 +288,16 @@ describe("updateValset tests", function () { "transfer amount exceeds balance" ); }); + it("throws on not whitelisted signer ", async function () { + await expect(runTest({ notWhiteListed: true })).to.be.revertedWith( + "The caller is not whitelisted for this operation" + ); + }); + it("throws on not already removed singer from whitelist ", async function () { + await expect(runTest({ removedWhitelist: true })).to.be.revertedWith( + "The caller is not whitelisted for this operation" + ); + }); it("pays reward correctly", async function () { let {gravity, checkpoint} = await runTest({ withReward: true }); @@ -251,6 +308,11 @@ describe("updateValset tests", function () { let { gravity, checkpoint } = await runTest({}); expect((await gravity.functions.state_lastValsetCheckpoint())[0]).to.equal(checkpoint); }); + + it("happy path with whitelisted signer", async function () { + let { gravity, checkpoint } = await runTest({ isWHitelisted:true}); + expect((await gravity.functions.state_lastValsetCheckpoint())[0]).to.equal(checkpoint); + }); }); // This test produces a hash for the contract which should match what is being used in the Go unit tests. It's here for From 105945b7a58e8c79bd0a9256b820ce1ba625df37 Mon Sep 17 00:00:00 2001 From: V-Staykov Date: Mon, 14 Mar 2022 17:03:06 +0200 Subject: [PATCH 2/3] aded fix to the failing test --- module/x/gravity/handler_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/module/x/gravity/handler_test.go b/module/x/gravity/handler_test.go index 2ff813687..d450d1997 100644 --- a/module/x/gravity/handler_test.go +++ b/module/x/gravity/handler_test.go @@ -77,7 +77,7 @@ func TestHandleMsgSendToEth(t *testing.T) { // send transaction not meeting the minimum transaction requirement sendingCoin.Amount = sdk.NewInt(4) - expectedErrMsg := "amount does not meet minimum sending amount requirement: 5" + expectedErrMsg := "amount does not meet minimum sending amount requirement: 5acudos: invalid" msg3 := &types.MsgSendToEth{ Sender: userCosmosAddr.String(), EthDest: ethDestination, @@ -91,7 +91,7 @@ func TestHandleMsgSendToEth(t *testing.T) { // send transaction not meeting the minimum transaction FEE requirement sendingCoin.Amount = sdk.NewInt(40) feeCoin.Amount = sdk.NewInt(4) - expectedErrMsg = "fee does not meet minimum fee requirement: 5" + expectedErrMsg = "fee does not meet minimum fee requirement: 5acudos: invalid" msg4 := &types.MsgSendToEth{ Sender: userCosmosAddr.String(), EthDest: ethDestination, From b93e74ff16054d96dc5a60f10a64ad10585605b5 Mon Sep 17 00:00:00 2001 From: maptuhec Date: Tue, 15 Mar 2022 15:40:14 +0200 Subject: [PATCH 3/3] Replace old access control with the Cudos one --- solidity/contract-deployer.ts | 9 ++- solidity/contracts/BridgeAccessControl.sol | 53 -------------- solidity/contracts/CudosAccessControls.sol | 84 ++++++++++++++++++++++ solidity/contracts/Gravity.sol | 14 ++-- solidity/hardhat.config.ts | 15 +++- solidity/test-utils/index.ts | 6 +- solidity/test/arbitrary-logic.ts | 18 ++--- solidity/test/constructor.ts | 12 ++-- solidity/test/deployERC20.ts | 10 +-- solidity/test/gas-test.ts | 12 ++-- solidity/test/happy-path.ts | 10 +-- solidity/test/sendToCosmos.ts | 10 +-- solidity/test/submitBatch-vs-logicCall.ts | 10 +-- solidity/test/submitBatch.ts | 16 ++--- solidity/test/updateValset.ts | 10 +-- solidity/test/withdrawERC20.ts | 18 ++--- 16 files changed, 175 insertions(+), 132 deletions(-) delete mode 100644 solidity/contracts/BridgeAccessControl.sol create mode 100644 solidity/contracts/CudosAccessControls.sol diff --git a/solidity/contract-deployer.ts b/solidity/contract-deployer.ts index 1de9d9a81..1e5cc2d16 100644 --- a/solidity/contract-deployer.ts +++ b/solidity/contract-deployer.ts @@ -3,7 +3,6 @@ import { TestERC20A } from "./typechain/TestERC20A"; import { TestERC20B } from "./typechain/TestERC20B"; import { TestERC20C } from "./typechain/TestERC20C"; import { TestUniswapLiquidity } from "./typechain/TestUniswapLiquidity"; -import { BridgeAccessControl } from "./typechain/BridgeAccessControl"; import { ethers } from "ethers"; import fs from "fs"; import commandLineArgs from "command-line-args"; @@ -185,12 +184,12 @@ async function deploy() { const gravityId = ethers.utils.formatBytes32String(gravityIdString); - let bridgeAccessControl:any - const AcArts = getContractArtifacts("artifacts/contracts/BridgeAccessControl.sol/BridgeAccessControl.json"); + let cudosAccessControl:any + const AcArts = getContractArtifacts("artifacts/contracts/CudosAccessControls.sol/CudosAccessControls.json"); const AcFactory = new ethers.ContractFactory(AcArts.abi, AcArts.bytecode, wallet); console.log("Deploying AccessControl contract...") - bridgeAccessControl = (await AcFactory.deploy()); + cudosAccessControl = (await AcFactory.deploy()); console.log("Starting Gravity contract deploy"); const { abi, bytecode } = getContractArtifacts(args["contract"]); @@ -232,7 +231,7 @@ async function deploy() { vote_power, eth_addresses, powers, - bridgeAccessControl.address + cudosAccessControl.address )) as Gravity; await gravity.deployed(); diff --git a/solidity/contracts/BridgeAccessControl.sol b/solidity/contracts/BridgeAccessControl.sol deleted file mode 100644 index ecb3a6598..000000000 --- a/solidity/contracts/BridgeAccessControl.sol +++ /dev/null @@ -1,53 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.6.6; - -import "@openzeppelin/contracts/access/AccessControl.sol"; - -contract BridgeAccessControl is AccessControl { - // Role definitions - bytes32 public constant WHITELISTED_ROLE = keccak256("WHITELISTED_ROLE"); - bytes32 public constant SMART_CONTRACT_ROLE = keccak256("SMART_CONTRACT_ROLE"); - - // Events - event AdminRoleGranted( - address indexed beneficiary, - address indexed caller - ); - - event AdminRoleRemoved( - address indexed beneficiary, - address indexed caller - ); - - modifier onlyAdminRole() { - require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "BridgeAccessControls: sender must be an admin"); - _; - } - - constructor() public { - _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); - } - - ///////////// - // Lookups // - ///////////// - - function hasAdminRole(address _address) external view returns (bool) { - return hasRole(DEFAULT_ADMIN_ROLE, _address); - } - - /////////////// - // Modifiers // - /////////////// - - function addAdminRole(address _address) external onlyAdminRole { - _setupRole(DEFAULT_ADMIN_ROLE, _address); - emit AdminRoleGranted(_address, _msgSender()); - } - - function removeAdminRole(address _address) external onlyAdminRole { - revokeRole(DEFAULT_ADMIN_ROLE, _address); - emit AdminRoleRemoved(_address, _msgSender()); - } -} \ No newline at end of file diff --git a/solidity/contracts/CudosAccessControls.sol b/solidity/contracts/CudosAccessControls.sol new file mode 100644 index 000000000..79ddac819 --- /dev/null +++ b/solidity/contracts/CudosAccessControls.sol @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: MIT + +pragma solidity 0.6.12; + +import "@openzeppelin/contracts/access/AccessControl.sol"; + +contract CudosAccessControls is AccessControl { + // Role definitions + bytes32 public constant WHITELISTED_ROLE = keccak256("WHITELISTED_ROLE"); + bytes32 public constant SMART_CONTRACT_ROLE = keccak256("SMART_CONTRACT_ROLE"); + // Events + event AdminRoleGranted( + address indexed beneficiary, + address indexed caller + ); + event AdminRoleRemoved( + address indexed beneficiary, + address indexed caller + ); + event WhitelistRoleGranted( + address indexed beneficiary, + address indexed caller + ); + event WhitelistRoleRemoved( + address indexed beneficiary, + address indexed caller + ); + event SmartContractRoleGranted( + address indexed beneficiary, + address indexed caller + ); + event SmartContractRoleRemoved( + address indexed beneficiary, + address indexed caller + ); + modifier onlyAdminRole() { + require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "CudosAccessControls: sender must be an admin"); + _; + } + + constructor() public { + _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); + } + + ///////////// + // Lookups // + ///////////// + function hasAdminRole(address _address) external view returns (bool) { + return hasRole(DEFAULT_ADMIN_ROLE, _address); + } + function hasWhitelistRole(address _address) external view returns (bool) { + return hasRole(WHITELISTED_ROLE, _address); + } + function hasSmartContractRole(address _address) external view returns (bool) { + return hasRole(SMART_CONTRACT_ROLE, _address); + } + /////////////// + // Modifiers // + /////////////// + function addAdminRole(address _address) external onlyAdminRole { + _setupRole(DEFAULT_ADMIN_ROLE, _address); + emit AdminRoleGranted(_address, _msgSender()); + } + function removeAdminRole(address _address) external onlyAdminRole { + revokeRole(DEFAULT_ADMIN_ROLE, _address); + emit AdminRoleRemoved(_address, _msgSender()); + } + function addWhitelistRole(address _address) external onlyAdminRole { + _setupRole(WHITELISTED_ROLE, _address); + emit WhitelistRoleGranted(_address, _msgSender()); + } + function removeWhitelistRole(address _address) external onlyAdminRole { + revokeRole(WHITELISTED_ROLE, _address); + emit WhitelistRoleRemoved(_address, _msgSender()); + } + function addSmartContractRole(address _address) external onlyAdminRole { + _setupRole(SMART_CONTRACT_ROLE, _address); + emit SmartContractRoleGranted(_address, _msgSender()); + } + function removeSmartContractRole(address _address) external onlyAdminRole { + revokeRole(SMART_CONTRACT_ROLE, _address); + emit SmartContractRoleRemoved(_address, _msgSender()); + } +} \ No newline at end of file diff --git a/solidity/contracts/Gravity.sol b/solidity/contracts/Gravity.sol index 31ce6b091..0660ef2e0 100644 --- a/solidity/contracts/Gravity.sol +++ b/solidity/contracts/Gravity.sol @@ -6,7 +6,7 @@ import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; import "@openzeppelin/contracts/utils/Address.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; import "./CosmosToken.sol"; -import "./BridgeAccessControl.sol"; +import "./CudosAccessControls.sol"; pragma experimental ABIEncoderV2; @@ -60,7 +60,7 @@ contract Gravity is ReentrancyGuard { bytes32 public state_gravityId; uint256 public state_powerThreshold; - BridgeAccessControl public bridgeAccessControl; + CudosAccessControls public cudosAccessControls; mapping(address => bool) public whitelisted; @@ -115,7 +115,7 @@ contract Gravity is ReentrancyGuard { modifier onlyWhitelisted() { require( - whitelisted[msg.sender] || bridgeAccessControl.hasAdminRole(msg.sender) , + whitelisted[msg.sender] || cudosAccessControls.hasAdminRole(msg.sender) , "The caller is not whitelisted for this operation" ); _; @@ -608,7 +608,7 @@ contract Gravity is ReentrancyGuard { function withdrawERC20( address _tokenAddress) external { - require(bridgeAccessControl.hasAdminRole(msg.sender), "Recipient is not an admin"); + require(cudosAccessControls.hasAdminRole(msg.sender), "Recipient is not an admin"); uint256 totalBalance = IERC20(_tokenAddress).balanceOf(address(this)); IERC20(_tokenAddress).safeTransfer(msg.sender , totalBalance); } @@ -622,13 +622,13 @@ contract Gravity is ReentrancyGuard { // arguments would never be used in this case address[] memory _validators, uint256[] memory _powers, - BridgeAccessControl _bridgeAccessControl + CudosAccessControls _cudosAccessControls ) public { // CHECKS // Check that validators, powers, and signatures (v,r,s) set is well-formed require(_validators.length == _powers.length, "Malformed current validator set"); - require(address(_bridgeAccessControl) != address(0), "Access control contract address is incorrect"); + require(address(_cudosAccessControls) != address(0), "Access control contract address is incorrect"); // Check cumulative power to ensure the contract has sufficient power to actually // pass a vote @@ -655,7 +655,7 @@ contract Gravity is ReentrancyGuard { state_powerThreshold = _powerThreshold; state_lastValsetCheckpoint = newCheckpoint; - bridgeAccessControl = _bridgeAccessControl; + cudosAccessControls = _cudosAccessControls; // LOGS diff --git a/solidity/hardhat.config.ts b/solidity/hardhat.config.ts index 2239fb2bd..a0a4b86b8 100644 --- a/solidity/hardhat.config.ts +++ b/solidity/hardhat.config.ts @@ -28,12 +28,25 @@ task("accounts", "Prints the list of accounts", async (args, hre) => { module.exports = { // This is a sample solc configuration that specifies which version of solc to use solidity: { + compilers: [ + { version: "0.6.6", settings: { optimizer: { enabled: true } - } }, + } + }, + { + version: "0.6.12", + settings: { + optimizer: { + enabled: true + } + } + } +] + }, networks: { hardhat: { timeout: 2000000, diff --git a/solidity/test-utils/index.ts b/solidity/test-utils/index.ts index 5036e3d40..4496d868a 100644 --- a/solidity/test-utils/index.ts +++ b/solidity/test-utils/index.ts @@ -1,6 +1,6 @@ import { Gravity } from "../typechain/Gravity"; import { TestERC20A } from "../typechain/TestERC20A"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { ethers } from "hardhat"; import { makeCheckpoint, signHash, getSignerAddresses, ZeroAddress } from "./pure"; import { Signer } from "ethers"; @@ -14,7 +14,7 @@ export async function deployContracts( powerThreshold: number, validators: Signer[], powers: number[], - bridgeAccessControl: String, + cudosAccessControl: String, opts?: DeployContractsOptions ) { const TestERC20 = await ethers.getContractFactory("TestERC20A"); @@ -31,7 +31,7 @@ export async function deployContracts( powerThreshold, await getSignerAddresses(validators), powers, - bridgeAccessControl + cudosAccessControl )) as Gravity; await gravity.deployed(); diff --git a/solidity/test/arbitrary-logic.ts b/solidity/test/arbitrary-logic.ts index 48f16e0c3..c8a46588a 100644 --- a/solidity/test/arbitrary-logic.ts +++ b/solidity/test/arbitrary-logic.ts @@ -3,7 +3,7 @@ import { ethers } from "hardhat"; import { solidity } from "ethereum-waffle"; import { TestLogicContract } from "../typechain/TestLogicContract"; import { SimpleLogicBatchMiddleware } from "../typechain/SimpleLogicBatchMiddleware"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { deployContracts } from "../test-utils"; import { @@ -36,10 +36,10 @@ async function runTest(opts: { // Prep and deploy contract // ======================== - let bridgeAccessControl: any + let cudosAccessControl: any - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = await BridgeAccessControl.deploy(); + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = await CudosAccessControls.deploy(); const signers = await ethers.getSigners(); const gravityId = ethers.utils.formatBytes32String("foo"); @@ -51,7 +51,7 @@ async function runTest(opts: { gravity, testERC20, checkpoint: deployCheckpoint - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); // First we deploy the logic batch middleware contract. This makes it easy to call a logic // contract a bunch of times in a batch. @@ -302,11 +302,11 @@ describe("submitLogicCall tests", function () { // This test produces a hash for the contract which should match what is being used in the Go unit tests. It's here for // the use of anyone updating the Go tests. describe("logicCall Go test hash", async function () { - let bridgeAccessControl:any + let cudosAccessControl:any beforeEach(async () => { - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = (await BridgeAccessControl.deploy()) as BridgeAccessControl; + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = (await CudosAccessControls.deploy()) as CudosAccessControls; }); it("produces good hash", async function () { @@ -323,7 +323,7 @@ describe("logicCall Go test hash", async function () { gravity, testERC20, checkpoint: deployCheckpoint - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); diff --git a/solidity/test/constructor.ts b/solidity/test/constructor.ts index fc7a62344..2a8fb4365 100644 --- a/solidity/test/constructor.ts +++ b/solidity/test/constructor.ts @@ -1,7 +1,7 @@ import chai from "chai"; import { ethers } from "hardhat"; import { solidity } from "ethereum-waffle"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { deployContracts } from "../test-utils"; import { @@ -18,11 +18,11 @@ const { expect } = chai; describe("constructor tests", function() { - let bridgeAccessControl:any + let cudosAccessControl:any beforeEach(async () => { - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = (await BridgeAccessControl.deploy()); + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = (await CudosAccessControls.deploy()); }); @@ -38,7 +38,7 @@ describe("constructor tests", function() { const powerThreshold = 6666; await expect( - deployContracts(gravityId, powerThreshold, validators, powers,bridgeAccessControl.address,) + deployContracts(gravityId, powerThreshold, validators, powers,cudosAccessControl.address,) ).to.be.revertedWith("Malformed current validator set"); }); @@ -53,7 +53,7 @@ describe("constructor tests", function() { const powerThreshold = 666666666; await expect( - deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address) + deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address) ).to.be.revertedWith( "Submitted validator set signatures do not have enough power" ); diff --git a/solidity/test/deployERC20.ts b/solidity/test/deployERC20.ts index 31f93fdcb..7a8214c09 100644 --- a/solidity/test/deployERC20.ts +++ b/solidity/test/deployERC20.ts @@ -2,7 +2,7 @@ import chai from "chai"; import { ethers } from "hardhat"; import { solidity } from "ethereum-waffle"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { deployContracts } from "../test-utils"; import { getSignerAddresses, @@ -18,10 +18,10 @@ const { expect } = chai; async function runTest(opts: {}) { - let bridgeAccessControl:any + let cudosAccessControl:any - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = (await BridgeAccessControl.deploy()); + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = (await CudosAccessControls.deploy()); // Prep and deploy Gravity contract // ======================== @@ -35,7 +35,7 @@ async function runTest(opts: {}) { gravity, testERC20, checkpoint: deployCheckpoint - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); diff --git a/solidity/test/gas-test.ts b/solidity/test/gas-test.ts index 8c3bb2a23..642fc77b5 100644 --- a/solidity/test/gas-test.ts +++ b/solidity/test/gas-test.ts @@ -1,7 +1,7 @@ import chai from "chai"; import { ethers } from "hardhat"; import { solidity } from "ethereum-waffle"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { deployContracts } from "../test-utils"; import { @@ -16,11 +16,11 @@ const { expect } = chai; describe("Gas tests", function () { - let bridgeAccessControl:any + let cudosAccessControl:any beforeEach(async () => { - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = (await BridgeAccessControl.deploy()) ; + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = (await CudosAccessControls.deploy()) ; }); it("makeCheckpoint in isolation", async function () { @@ -37,7 +37,7 @@ describe("Gas tests", function () { gravity, testERC20, checkpoint: deployCheckpoint - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); let valset = { validators: await getSignerAddresses(validators), @@ -67,7 +67,7 @@ describe("Gas tests", function () { gravity, testERC20, checkpoint: deployCheckpoint - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); let sigs = await signHash( validators, diff --git a/solidity/test/happy-path.ts b/solidity/test/happy-path.ts index 604355416..ac6a4630b 100644 --- a/solidity/test/happy-path.ts +++ b/solidity/test/happy-path.ts @@ -2,7 +2,7 @@ import chai from "chai"; import { ethers } from "hardhat"; import { solidity } from "ethereum-waffle"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { deployContracts } from "../test-utils"; import { getSignerAddresses, @@ -18,11 +18,11 @@ const { expect } = chai; describe("Gravity happy path valset update + batch submit", function () { - let bridgeAccessControl:any + let cudosAccessControl:any beforeEach(async () => { - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = (await BridgeAccessControl.deploy()); + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = (await CudosAccessControls.deploy()); }); @@ -50,7 +50,7 @@ describe("Gravity happy path valset update + batch submit", function () { gravity, testERC20, checkpoint: deployCheckpoint - } = await deployContracts(gravityId, powerThreshold, valset0.validators, valset0.powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, valset0.validators, valset0.powers, cudosAccessControl.address); diff --git a/solidity/test/sendToCosmos.ts b/solidity/test/sendToCosmos.ts index beb500ce5..84843bf4b 100644 --- a/solidity/test/sendToCosmos.ts +++ b/solidity/test/sendToCosmos.ts @@ -3,7 +3,7 @@ import chai from "chai"; import { ethers } from "hardhat"; import { solidity } from "ethereum-waffle"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { deployContracts } from "../test-utils"; import { getSignerAddresses, @@ -16,13 +16,13 @@ import { chai.use(solidity); const { expect } = chai; -let bridgeAccessControl:any +let cudosAccessControl:any async function runTest(opts: {}) { - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = (await BridgeAccessControl.deploy()); + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = (await CudosAccessControls.deploy()); // Prep and deploy contract // ======================== const signers = await ethers.getSigners(); @@ -35,7 +35,7 @@ async function runTest(opts: {}) { gravity, testERC20, checkpoint: deployCheckpoint - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); // Transfer out to Cosmos, locking coins diff --git a/solidity/test/submitBatch-vs-logicCall.ts b/solidity/test/submitBatch-vs-logicCall.ts index d03c55582..8bcc64165 100644 --- a/solidity/test/submitBatch-vs-logicCall.ts +++ b/solidity/test/submitBatch-vs-logicCall.ts @@ -4,7 +4,7 @@ import { ethers } from "hardhat"; import { solidity } from "ethereum-waffle"; import { TestTokenBatchMiddleware } from "../typechain/TestTokenBatchMiddleware"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { deployContracts } from "../test-utils"; import { getSignerAddresses, @@ -21,7 +21,7 @@ import { ReentrantERC20 } from "../typechain/ReentrantERC20"; chai.use(solidity); const { expect } = chai; -let bridgeAccessControl:any +let cudosAccessControl:any async function prepareTxBatch(batchSize: number, signers: Signer[]) { const numTxs = batchSize; @@ -61,8 +61,8 @@ async function prep() { // Deploy contracts // ================ - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = (await BridgeAccessControl.deploy()); + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = (await CudosAccessControls.deploy()); const signers = await ethers.getSigners(); const gravityId = ethers.utils.formatBytes32String("foo"); @@ -76,7 +76,7 @@ async function prep() { powerThreshold, validators, powers, - bridgeAccessControl.address + cudosAccessControl.address ); const ReentrantERC20Contract = await ethers.getContractFactory( diff --git a/solidity/test/submitBatch.ts b/solidity/test/submitBatch.ts index 14246ab56..d2dd1811e 100644 --- a/solidity/test/submitBatch.ts +++ b/solidity/test/submitBatch.ts @@ -2,7 +2,7 @@ import chai from "chai"; import { ethers } from "hardhat"; import { solidity } from "ethereum-waffle"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { deployContracts } from "../test-utils"; import { getSignerAddresses, @@ -16,7 +16,7 @@ import { connect } from "node:http2"; chai.use(solidity); const { expect } = chai; -let bridgeAccessControl:any +let cudosAccessControl:any async function runTest(opts: { // Issues with the tx batch @@ -36,8 +36,8 @@ async function runTest(opts: { - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = (await BridgeAccessControl.deploy()); + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = (await CudosAccessControls.deploy()); // Prep and deploy contract // ======================== @@ -51,7 +51,7 @@ async function runTest(opts: { gravity, testERC20, checkpoint: deployCheckpoint, - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); // Transfer out to Cosmos, locking coins // ===================================== @@ -280,7 +280,7 @@ describe("submitBatch Go test hash", function () { gravity, testERC20, checkpoint: deployCheckpoint, - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); // Prepare batch // =============================== @@ -379,7 +379,7 @@ it("produces good hash with newly whitelisted address", async function () { gravity, testERC20, checkpoint: deployCheckpoint, - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); // Prepare batch // =============================== @@ -479,7 +479,7 @@ it("throws when an address is removed from the whitelist", async function () { gravity, testERC20, checkpoint: deployCheckpoint, - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); // Prepare batch // =============================== diff --git a/solidity/test/updateValset.ts b/solidity/test/updateValset.ts index d93c6cb90..ab4f09489 100644 --- a/solidity/test/updateValset.ts +++ b/solidity/test/updateValset.ts @@ -3,7 +3,7 @@ import chai from "chai"; import { ethers} from "hardhat"; import { solidity } from "ethereum-waffle"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { deployContracts } from "../test-utils"; import { getSignerAddresses, @@ -35,10 +35,10 @@ async function runTest(opts: { removedWhitelist:? boolean; }) { - let bridgeAccessControl:any + let cudosAccessControl:any - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = (await BridgeAccessControl.deploy()); + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = (await CudosAccessControls.deploy()); const signers = await ethers.getSigners(); const gravityId = ethers.utils.formatBytes32String("foo"); @@ -53,7 +53,7 @@ async function runTest(opts: { gravity, testERC20, checkpoint: deployCheckpoint - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); let newPowers = examplePowers(); newPowers[0] -= 3; diff --git a/solidity/test/withdrawERC20.ts b/solidity/test/withdrawERC20.ts index c24bdfcd2..e394c7380 100644 --- a/solidity/test/withdrawERC20.ts +++ b/solidity/test/withdrawERC20.ts @@ -1,7 +1,7 @@ import chai from "chai"; import { ethers } from "hardhat"; import { solidity } from "ethereum-waffle"; -import { BridgeAccessControl } from "../typechain/BridgeAccessControl"; +import { CudosAccessControls } from "../typechain/CudosAccessControls"; import { Gravity } from "../typechain/Gravity"; import { TestERC20A } from "../typechain/TestERC20A"; @@ -17,15 +17,15 @@ const { expect } = chai; describe("Withdraw ERC20 Bridge Tests", function() { - let bridgeAccessControl:any + let cudosAccessControl:any let gravityInstance: Gravity let testERC20Instance: TestERC20A let amountToTrasnfer:any beforeEach(async () => { - const BridgeAccessControl = await ethers.getContractFactory("BridgeAccessControl"); - bridgeAccessControl = (await BridgeAccessControl.deploy()); + const CudosAccessControls = await ethers.getContractFactory("CudosAccessControls"); + cudosAccessControl = (await CudosAccessControls.deploy()); const signers = await ethers.getSigners(); const gravityId = ethers.utils.formatBytes32String("foo"); @@ -37,7 +37,7 @@ describe("Withdraw ERC20 Bridge Tests", function() { gravity, testERC20, checkpoint: deployCheckpoint - } = await deployContracts(gravityId, powerThreshold, validators, powers, bridgeAccessControl.address); + } = await deployContracts(gravityId, powerThreshold, validators, powers, cudosAccessControl.address); gravityInstance = gravity testERC20Instance = testERC20 @@ -50,14 +50,14 @@ describe("Withdraw ERC20 Bridge Tests", function() { it("deployer should have admin role", async function() { const signers = await ethers.getSigners(); - const hasRole = await bridgeAccessControl.hasAdminRole(signers[0].address) + const hasRole = await cudosAccessControl.hasAdminRole(signers[0].address) expect(hasRole).to.be.true; }); - it("the bridgeAccessControl address would be set properly", async function() { - const accessControlAddress = await gravityInstance.bridgeAccessControl(); + it("the cudosAccessControl address would be set properly", async function() { + const accessControlAddress = await gravityInstance.cudosAccessControls(); - expect(bridgeAccessControl.address).to.be.equal(accessControlAddress) + expect(cudosAccessControl.address).to.be.equal(accessControlAddress) }) it("should be able to withdraw ERC20 tokens from the bridge", async function() {