From 72666c21d614def86b05299bf8b7841c884efad1 Mon Sep 17 00:00:00 2001 From: Krzysztof Ziobro <86822080+krzysztofziobro@users.noreply.github.com> Date: Tue, 12 Dec 2023 14:15:03 +0100 Subject: [PATCH] Add pipeline that checks code formatting (#41) * Add pipeline that checks code formatting * Fix makefile + format code * Add hardhat scripts to format * Add remaining js files --- .github/workflows/check-formatting.yml | 25 + Makefile | 48 ++ azero/contracts/most/lib.rs | 10 +- azero/contracts/tests/lib.rs | 78 +-- azero/gulpfile.js | 12 +- azero/scripts/deploy.ts | 48 +- eth/gulpfile.js | 12 +- eth/hardhat.config.js | 101 ++- eth/scripts/1_deploy_contracts.js | 121 ++-- eth/scripts/2_setup_contracts.js | 86 +-- eth/test/BenchmarkMost.js | 8 +- eth/test/Most.js | 842 +++++++++++++------------ relayer/src/contracts/eth.rs | 5 +- relayer/src/listeners/azero.rs | 3 +- relayer/src/listeners/eth.rs | 3 +- 15 files changed, 754 insertions(+), 648 deletions(-) create mode 100644 .github/workflows/check-formatting.yml diff --git a/.github/workflows/check-formatting.yml b/.github/workflows/check-formatting.yml new file mode 100644 index 00000000..8b7a7fcd --- /dev/null +++ b/.github/workflows/check-formatting.yml @@ -0,0 +1,25 @@ + +name: Check formatting + +on: + pull_request: + branches: + - master + push: + branches: + - master + +jobs: + test: + name: Check formatting + runs-on: [self-hosted, Linux, X64, large] + steps: + - name: Checkout code + uses: actions/checkout@v3 + + - name: "Install Rust toolchain" + uses: Cardinal-Cryptography/aleph-node/.github/actions/install-rust-toolchain@5eda3cd85e7e3aec3f2db7a26631c65d52c4b9ea + + - name: Check code formatting + shell: bash + run: make format-check diff --git a/Makefile b/Makefile index 1420249b..67e5907a 100644 --- a/Makefile +++ b/Makefile @@ -189,3 +189,51 @@ ink-lint: .PHONY: contracts-lint contracts-lint: # Lint contracts contracts-lint: solidity-lint ink-lint + +.PHONY: rust-format-check +rust-format-check: # Check rust code formatting +rust-format-check: + cd relayer && cargo fmt -- --check + cd azero/contracts/most && cargo fmt -- --check + cd azero/contracts/governance && cargo fmt -- --check + cd azero/contracts/token && cargo fmt -- --check + cd azero/contracts/psp22-traits && cargo fmt -- --check + cd azero/contracts/tests && cargo fmt -- --check + +.PHONY: rust-format +rust-format: # Format rust code +rust-format: + cd relayer && cargo fmt + cd azero/contracts/most && cargo fmt + cd azero/contracts/governance && cargo fmt + cd azero/contracts/token && cargo fmt + cd azero/contracts/psp22-traits && cargo fmt + cd azero/contracts/tests && cargo fmt + +.PHONY: js-format-check +js-format-check: # Check js formatting +js-format-check: + cd eth && npx prettier --check test + cd eth && npx prettier --check scripts + cd eth && npx prettier --check gulpfile.js + cd eth && npx prettier --check hardhat.config.js + cd azero && npx prettier --check scripts + cd azero && npx prettier --check gulpfile.js + +.PHONY: js-format +js-format: # Format js code +js-format: + cd eth && npx prettier --write test + cd eth && npx prettier --write scripts + cd eth && npx prettier --write gulpfile.js + cd eth && npx prettier --write hardhat.config.js + cd azero && npx prettier --write scripts + cd azero && npx prettier --write gulpfile.js + +.PHONY: format-check +format-check: # Check code formatting +format-check: rust-format-check js-format-check + +.PHONY: format +format: # Format code +format: rust-format js-format diff --git a/azero/contracts/most/lib.rs b/azero/contracts/most/lib.rs index 20dac6f5..d3c6335d 100755 --- a/azero/contracts/most/lib.rs +++ b/azero/contracts/most/lib.rs @@ -589,10 +589,7 @@ pub mod most { /// Returns an error (reverts) if account is not in the currently active committee #[ink(message)] - pub fn only_current_committee_member( - &self, - account: AccountId, - ) -> Result<(), MostError> { + pub fn only_current_committee_member(&self, account: AccountId) -> Result<(), MostError> { match self.is_in_committee(self.committee_id, account) { true => Ok(()), false => Err(MostError::NotInCommittee), @@ -833,10 +830,7 @@ pub mod most { ) .expect("Threshold is valid."); set_caller::(accounts.bob); - assert_eq!( - most.ensure_owner(), - Err(MostError::NotOwner(accounts.bob)) - ); + assert_eq!(most.ensure_owner(), Err(MostError::NotOwner(accounts.bob))); set_caller::(accounts.alice); assert_eq!(most.ensure_owner(), Ok(())); assert_eq!(most.set_owner(accounts.bob), Ok(())); diff --git a/azero/contracts/tests/lib.rs b/azero/contracts/tests/lib.rs index f2c5b552..b8e67055 100644 --- a/azero/contracts/tests/lib.rs +++ b/azero/contracts/tests/lib.rs @@ -70,8 +70,7 @@ mod e2e { #[ink_e2e::test] fn owner_can_add_a_new_pair(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, false).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, false).await; let add_pair_res = most_add_pair( &mut client, @@ -87,8 +86,7 @@ mod e2e { #[ink_e2e::test] fn non_owner_cannot_add_a_new_pair(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, false).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, false).await; let add_pair_res = most_add_pair( &mut client, @@ -107,8 +105,7 @@ mod e2e { #[ink_e2e::test] fn send_request_burns_tokens(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, true).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, true).await; let base_fee = most_base_fee(&mut client, most_address) .await @@ -136,7 +133,8 @@ mod e2e { REMOTE_RECEIVER, base_fee, ) - .await.expect("send request should succeed"); + .await + .expect("send request should succeed"); let balance_after = psp22_balance_of( &mut client, @@ -165,8 +163,7 @@ mod e2e { #[ink_e2e::test] fn send_request_fails_on_non_whitelisted_token(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, false).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, false).await; let amount_to_send = 1000; @@ -193,8 +190,7 @@ mod e2e { #[ink_e2e::test] fn correct_request(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, true).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, true).await; let amount_to_send = 1000; @@ -240,8 +236,7 @@ mod e2e { #[ink_e2e::test] fn receive_request_can_only_be_called_by_guardians(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, false).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, false).await; let amount = 20; let receiver_address = account_id(AccountKeyring::One); @@ -270,8 +265,7 @@ mod e2e { #[ink_e2e::test] fn receive_request_non_matching_hash(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, false).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, false).await; let amount = 20; let receiver_address = account_id(AccountKeyring::One); @@ -300,8 +294,7 @@ mod e2e { fn receive_request_executes_request_after_enough_confirmations( mut client: ink_e2e::Client, ) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, false).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, false).await; let amount = 841189100000000; @@ -358,8 +351,7 @@ mod e2e { #[ink_e2e::test] fn receive_request_not_enough_signatures(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, false).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, false).await; let amount = 20; let receiver_address = account_id(AccountKeyring::One); @@ -409,8 +401,7 @@ mod e2e { #[ink_e2e::test] fn amount_below_minimum(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, true).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, true).await; let base_fee = most_base_fee(&mut client, most_address) .await @@ -446,8 +437,7 @@ mod e2e { #[ink_e2e::test] fn base_fee_too_low(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, true).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, true).await; let base_fee = most_base_fee(&mut client, most_address) .await @@ -474,8 +464,7 @@ mod e2e { #[ink_e2e::test] fn pocket_money(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, false).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, false).await; // seed contract with some funds for pocket money transfers let call_data = vec![ @@ -528,8 +517,7 @@ mod e2e { #[ink_e2e::test] fn committee_rewards(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, false).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, false).await; let commission = most_commission_per_dix_mille(&mut client, most_address).await; @@ -642,8 +630,7 @@ mod e2e { #[ink_e2e::test] fn past_committee_rewards(mut client: ink_e2e::Client) { - let (most_address, token_address) = - setup_default_most_and_token(&mut client, false).await; + let (most_address, token_address) = setup_default_most_and_token(&mut client, false).await; let amount = 841189100000000; let receiver_address = account_id(AccountKeyring::One); @@ -825,15 +812,9 @@ mod e2e { .await; if add_pair { - most_add_pair( - client, - &alice(), - most_address, - token_address, - REMOTE_TOKEN, - ) - .await - .expect("Add pair should succeed"); + most_add_pair(client, &alice(), most_address, token_address, REMOTE_TOKEN) + .await + .expect("Add pair should succeed"); } (most_address, token_address) @@ -908,13 +889,7 @@ mod e2e { caller, most, |most| { - most.receive_request( - request_hash, - token, - amount, - receiver_address, - request_nonce, - ) + most.receive_request(request_hash, token, amount, receiver_address, request_nonce) }, None, ) @@ -939,10 +914,7 @@ mod e2e { .await } - async fn most_base_fee( - client: &mut E2EClient, - most: AccountId, - ) -> Result { + async fn most_base_fee(client: &mut E2EClient, most: AccountId) -> Result { call_message::( client, &alice(), @@ -999,8 +971,8 @@ mod e2e { client: &mut E2EClient, most_address: AccountId, ) -> Result { - let call = build_message::(most_address) - .call(|most| most.get_current_committee_id()); + let call = + build_message::(most_address).call(|most| most.get_current_committee_id()); Ok(client .call_dry_run(&alice(), &call, 0, None) @@ -1012,8 +984,8 @@ mod e2e { client: &mut E2EClient, most_address: AccountId, ) -> u128 { - let call = build_message::(most_address) - .call(|most| most.get_commission_per_dix_mille()); + let call = + build_message::(most_address).call(|most| most.get_commission_per_dix_mille()); client .call_dry_run(&alice(), &call, 0, None) diff --git a/azero/gulpfile.js b/azero/gulpfile.js index fe2af744..bf179514 100644 --- a/azero/gulpfile.js +++ b/azero/gulpfile.js @@ -1,10 +1,10 @@ -const gulp = require('gulp'); -const shell = require('gulp-shell') +const gulp = require("gulp"); +const shell = require("gulp-shell"); -gulp.task('compile', shell.task('npm run compile')) +gulp.task("compile", shell.task("npm run compile")); -gulp.task('watch', function () { - gulp.watch("contracts/*/*.rs", gulp.series('compile')); +gulp.task("watch", function () { + gulp.watch("contracts/*/*.rs", gulp.series("compile")); }); -gulp.task('default', gulp.series('watch')); +gulp.task("default", gulp.series("watch")); diff --git a/azero/scripts/deploy.ts b/azero/scripts/deploy.ts index 79096d51..59b04f0d 100644 --- a/azero/scripts/deploy.ts +++ b/azero/scripts/deploy.ts @@ -1,10 +1,15 @@ -import { ApiPromise, WsProvider, Keyring } from '@polkadot/api'; -import MostConstructors from '../types/constructors/most'; -import TokenConstructors from '../types/constructors/token'; -import GovernanceConstructors from '../types/constructors/governance'; -import { uploadCode, Addresses, storeAddresses, estimateContractInit } from './utils'; -import 'dotenv/config'; -import '@polkadot/api-augment'; +import { ApiPromise, WsProvider, Keyring } from "@polkadot/api"; +import MostConstructors from "../types/constructors/most"; +import TokenConstructors from "../types/constructors/token"; +import GovernanceConstructors from "../types/constructors/governance"; +import { + uploadCode, + Addresses, + storeAddresses, + estimateContractInit, +} from "./utils"; +import "dotenv/config"; +import "@polkadot/api-augment"; const envFile = process.env.AZERO_ENV || "dev"; async function import_env() { @@ -20,7 +25,7 @@ async function main(): Promise { commission_per_dix_mille, pocket_money, minimum_transfer_amount_usd, - relay_gas_usage + relay_gas_usage, } = await import_env(); let wsProvider = new WsProvider(ws_node); @@ -33,7 +38,7 @@ async function main(): Promise { console.log("token code hash:", tokenCodeHash); const mostCodeHash = await uploadCode(api, deployer, "most.contract"); - console.log('most code hash:', mostCodeHash); + console.log("most code hash:", mostCodeHash); const governanceCodeHash = await uploadCode( api, @@ -46,14 +51,19 @@ async function main(): Promise { const mostConstructors = new MostConstructors(api, deployer); const tokenConstructors = new TokenConstructors(api, deployer); - let estimatedGasMost = await estimateContractInit(api, deployer, 'most.contract', [ - [authority], - signature_threshold!, - commission_per_dix_mille!, - pocket_money!, - minimum_transfer_amount_usd!, - relay_gas_usage!, - ]); + let estimatedGasMost = await estimateContractInit( + api, + deployer, + "most.contract", + [ + [authority], + signature_threshold!, + commission_per_dix_mille!, + pocket_money!, + minimum_transfer_amount_usd!, + relay_gas_usage!, + ], + ); const { address: mostAddress } = await mostConstructors.new( [authority], @@ -65,7 +75,7 @@ async function main(): Promise { { gasLimit: estimatedGasMost }, ); - console.log('most address:', mostAddress); + console.log("most address:", mostAddress); let estimatedGasToken = await estimateContractInit( api, @@ -98,7 +108,7 @@ async function main(): Promise { const addresses: Addresses = { governance: governanceAddress, most: mostAddress, - weth: wethAddress + weth: wethAddress, }; console.log("addresses:", addresses); diff --git a/eth/gulpfile.js b/eth/gulpfile.js index b316aaa7..9af5d2b7 100644 --- a/eth/gulpfile.js +++ b/eth/gulpfile.js @@ -1,10 +1,10 @@ -const gulp = require('gulp'); -const shell = require('gulp-shell') +const gulp = require("gulp"); +const shell = require("gulp-shell"); -gulp.task('compile', shell.task('npx hardhat compile')) +gulp.task("compile", shell.task("npx hardhat compile")); -gulp.task('watch', function () { - gulp.watch("contracts/*.sol", gulp.series('compile')); +gulp.task("watch", function () { + gulp.watch("contracts/*.sol", gulp.series("compile")); }); -gulp.task('default', gulp.series('watch')); +gulp.task("default", gulp.series("watch")); diff --git a/eth/hardhat.config.js b/eth/hardhat.config.js index 40b35ae7..ba3b8f1d 100644 --- a/eth/hardhat.config.js +++ b/eth/hardhat.config.js @@ -1,5 +1,5 @@ require("@nomicfoundation/hardhat-toolbox"); -require('@openzeppelin/hardhat-upgrades'); +require("@openzeppelin/hardhat-upgrades"); require("@nomicfoundation/hardhat-chai-matchers"); require("@nomiclabs/hardhat-truffle5"); @@ -9,57 +9,56 @@ const DEV_MNEMONIC = "harsh master island dirt equip search awesome double turn crush wool grant"; module.exports = { - defaultNetwork: "hardhat", - networks: { - hardhat: { + defaultNetwork: "hardhat", + networks: { + hardhat: {}, + development: { + url: "http://127.0.0.1:8545", + accounts: { + mnemonic: DEV_MNEMONIC, }, - development: { - url: "http://127.0.0.1:8545", - accounts: { - mnemonic: DEV_MNEMONIC, + gas: 25e6, // Gas limit + gasPrice: 20e9, + }, + bridgenet: { + url: "https://rpc-eth-bridgenet.dev.azero.dev", + accounts: { + mnemonic: DEV_MNEMONIC, + }, + chainId: 12345, + gas: 25e6, // Gas limit + gasPrice: 20e9, + }, + }, + solidity: { + compilers: [ + { + version: "0.8.20", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, }, - gas: 25e6, // Gas limit - gasPrice: 20e9, }, - bridgenet: { - url: "https://rpc-eth-bridgenet.dev.azero.dev", - accounts: { - mnemonic: DEV_MNEMONIC, + { + version: "0.4.18", + settings: { + optimizer: { + enabled: true, + runs: 200, + }, }, - chainId: 12345, - gas: 25e6, // Gas limit - gasPrice: 20e9, - } - }, - solidity: { - compilers: [ - { - version: "0.8.20", - settings: { - optimizer: { - enabled: true, - runs: 200 - } - } - }, - { - version: "0.4.18", - settings: { - optimizer: { - enabled: true, - runs: 200 - } - } - }, - ] - }, - paths: { - sources: "./contracts", - tests: "./test", - cache: "./cache", - artifacts: "./artifacts" - }, - mocha: { - timeout: 40000 - } - } + }, + ], + }, + paths: { + sources: "./contracts", + tests: "./test", + cache: "./cache", + artifacts: "./artifacts", + }, + mocha: { + timeout: 40000, + }, +}; diff --git a/eth/scripts/1_deploy_contracts.js b/eth/scripts/1_deploy_contracts.js index 666d883d..c2e23e1d 100644 --- a/eth/scripts/1_deploy_contracts.js +++ b/eth/scripts/1_deploy_contracts.js @@ -1,77 +1,82 @@ const fs = require("node:fs"); const { ethers, upgrades } = require("hardhat"); -const COMMISSION_PER_DIX_MILLE=30 -const MINIMUM_TRANSFER_AMOUNT_USD=50 +const COMMISSION_PER_DIX_MILLE = 30; +const MINIMUM_TRANSFER_AMOUNT_USD = 50; async function main() { - const signers = await ethers.getSigners(); - const accounts = signers.map(s => s.address) + const signers = await ethers.getSigners(); + const accounts = signers.map((s) => s.address); - console.log("Using ", accounts [0], "as signer"); + console.log("Using ", accounts[0], "as signer"); - const WETH9 = await ethers.getContractFactory("WETH9"); - console.log("Deploying WETH9..."); - const weth9 = await WETH9.deploy(); - console.log("WETH9 deployed to:", weth9.target); + const WETH9 = await ethers.getContractFactory("WETH9"); + console.log("Deploying WETH9..."); + const weth9 = await WETH9.deploy(); + console.log("WETH9 deployed to:", weth9.target); - const Token = await ethers.getContractFactory("Token"); - console.log("Deploying USDT..."); - const usdt = await Token.deploy("12000000000000000000000000", "Tether", "USDT"); - console.log("USDT deployed to:", usdt.target); + const Token = await ethers.getContractFactory("Token"); + console.log("Deploying USDT..."); + const usdt = await Token.deploy( + "12000000000000000000000000", + "Tether", + "USDT", + ); + console.log("USDT deployed to:", usdt.target); - const Governance = await ethers.getContractFactory("Governance"); - const governance = await upgrades.deployProxy(Governance, - [ - accounts.slice(0, 1), - 1 - ], - { - initializer: "initialize", - kind: 'uups' - }); - await governance.waitForDeployment(); - console.log("Governance deployed to:", governance.target); + const Governance = await ethers.getContractFactory("Governance"); + const governance = await upgrades.deployProxy( + Governance, + [accounts.slice(0, 1), 1], + { + initializer: "initialize", + kind: "uups", + }, + ); + await governance.waitForDeployment(); + console.log("Governance deployed to:", governance.target); - const Most = await ethers.getContractFactory("Most"); - console.log("Deploying Most..."); - const most = await upgrades.deployProxy(Most, - [ - accounts.slice(0, 1), - 1, - COMMISSION_PER_DIX_MILLE, - MINIMUM_TRANSFER_AMOUNT_USD, - accounts [0], - ], - { - initializer: "initialize", - kind: 'uups' - }); - await most.waitForDeployment(); - console.log("Most deployed to:", most.target); + const Most = await ethers.getContractFactory("Most"); + console.log("Deploying Most..."); + const most = await upgrades.deployProxy( + Most, + [ + accounts.slice(0, 1), + 1, + COMMISSION_PER_DIX_MILLE, + MINIMUM_TRANSFER_AMOUNT_USD, + accounts[0], + ], + { + initializer: "initialize", + kind: "uups", + }, + ); + await most.waitForDeployment(); + console.log("Most deployed to:", most.target); - const Migrations = await ethers.getContractFactory("Migrations"); - const migrations = await Migrations.deploy(); - console.log("migrations deployed to:", migrations.target); + const Migrations = await ethers.getContractFactory("Migrations"); + const migrations = await Migrations.deploy(); + console.log("migrations deployed to:", migrations.target); - console.log("Updating migrations..."); - await migrations.setCompleted (1); + console.log("Updating migrations..."); + await migrations.setCompleted(1); - // --- spit addresses + // --- spit addresses - const addresses = { - migrations: migrations.target, - governance: governance.target, - most: most.target, - weth9: weth9.target, - usdt: usdt.target, - }; + const addresses = { + migrations: migrations.target, + governance: governance.target, + most: most.target, + weth9: weth9.target, + usdt: usdt.target, + }; - console.log(addresses); - fs.writeFileSync("addresses.json", JSON.stringify(addresses)); + console.log(addresses); + fs.writeFileSync("addresses.json", JSON.stringify(addresses)); } main().catch((error) => { - console.error(error); - process.exitCode = 1; + console.error(error); + process.exitCode = 1; }); diff --git a/eth/scripts/2_setup_contracts.js b/eth/scripts/2_setup_contracts.js index 801d2d8f..4b842667 100644 --- a/eth/scripts/2_setup_contracts.js +++ b/eth/scripts/2_setup_contracts.js @@ -3,46 +3,54 @@ const { ethers, artifacts } = require("hardhat"); const contracts = require("../addresses.json"); async function main() { - const signers = await ethers.getSigners(); - accounts = signers.map(s => s.address) - - console.log("Using ", accounts [0], "as signer"); - - // --- setup - - const Governance = artifacts.require ("Governance"); - const governance = await Governance.at (contracts.governance); - - let initialGovernanceOwner = await governance.owner(); - console.log("Transferring Governance ownership from ", initialGovernanceOwner, "to ", governance.address); - await governance.transferOwnership(contracts.governance); - console.log("Governance ownership transferred successfully"); - - const Most = artifacts.require ("Most"); - const most = await Most.at (contracts.most); - - const payload = ethers.zeroPadValue(ethers.getBytes( - contracts.usdt - ), 32); - console.log("Setting USDT address in Most to:", payload); - await most.setUSDT(payload); - - let initialMostOwner = await most.owner(); - console.log("Transferring Most ownership from ", initialMostOwner, "to", contracts.governance); - await most.transferOwnership(contracts.governance); - console.log("Most ownership transferred successfully"); - - const Migrations = artifacts.require ("Migrations"); - const migrations = await Migrations.at (contracts.migrations); - - let lastCompletedMigration = await migrations.last_completed_migration (); - console.log("Updating migrations from ", lastCompletedMigration, " to ", 2); - await migrations.setCompleted (2); - - console.log("Done"); + const signers = await ethers.getSigners(); + accounts = signers.map((s) => s.address); + + console.log("Using ", accounts[0], "as signer"); + + // --- setup + + const Governance = artifacts.require("Governance"); + const governance = await Governance.at(contracts.governance); + + let initialGovernanceOwner = await governance.owner(); + console.log( + "Transferring Governance ownership from ", + initialGovernanceOwner, + "to ", + governance.address, + ); + await governance.transferOwnership(contracts.governance); + console.log("Governance ownership transferred successfully"); + + const Most = artifacts.require("Most"); + const most = await Most.at(contracts.most); + + const payload = ethers.zeroPadValue(ethers.getBytes(contracts.usdt), 32); + console.log("Setting USDT address in Most to:", payload); + await most.setUSDT(payload); + + let initialMostOwner = await most.owner(); + console.log( + "Transferring Most ownership from ", + initialMostOwner, + "to", + contracts.governance, + ); + await most.transferOwnership(contracts.governance); + console.log("Most ownership transferred successfully"); + + const Migrations = artifacts.require("Migrations"); + const migrations = await Migrations.at(contracts.migrations); + + let lastCompletedMigration = await migrations.last_completed_migration(); + console.log("Updating migrations from ", lastCompletedMigration, " to ", 2); + await migrations.setCompleted(2); + + console.log("Done"); } main().catch((error) => { - console.error(error); - process.exitCode = 1; + console.error(error); + process.exitCode = 1; }); diff --git a/eth/test/BenchmarkMost.js b/eth/test/BenchmarkMost.js index 128c0216..a303722d 100644 --- a/eth/test/BenchmarkMost.js +++ b/eth/test/BenchmarkMost.js @@ -24,11 +24,9 @@ describe("MostBenchmark", function () { const tokenAddress = await testTokenInstance.getAddress(); const Most = await hre.ethers.getContractFactory("Most"); - const mostInstance = await Most.deploy( - guardianAddresses, - threshold, - { from: accounts[0] }, - ); + const mostInstance = await Most.deploy(guardianAddresses, threshold, { + from: accounts[0], + }); const mostInstanceAddress = await mostInstance.getAddress(); // Easy way to get a "random" bytes32 value diff --git a/eth/test/Most.js b/eth/test/Most.js index 67225951..32ce7ae2 100644 --- a/eth/test/Most.js +++ b/eth/test/Most.js @@ -1,7 +1,9 @@ const { expect } = require("chai"); const { ethers, upgrades } = require("hardhat"); -const { loadFixture } = require("@nomicfoundation/hardhat-toolbox/network-helpers"); -const { execSync: exec } = require('child_process'); +const { + loadFixture, +} = require("@nomicfoundation/hardhat-toolbox/network-helpers"); +const { execSync: exec } = require("child_process"); // Import utils const { addressToBytes32, getRandomAlephAccount } = require("./TestUtils"); @@ -14,420 +16,470 @@ const MINIMUM_TRANSFER_AMOUNT_USD = 50; const DIX_MILLE = 10000; describe("Most", function () { - describe("Constructor", function () { - it("Reverts if threshold is 0", async () => { - const signers = await ethers.getSigners(); - const accounts = signers.map(s => s.address) - - const Most = await ethers.getContractFactory("Most"); - await expect(upgrades.deployProxy(Most, - [ - [accounts[0]], - 0, - COMMISSION_PER_DIX_MILLE, - MINIMUM_TRANSFER_AMOUNT_USD, - accounts [0], - ], - { - initializer: "initialize", - kind: 'uups' - })).to.be.revertedWith("Signature threshold must be greater than 0"); - }); - it("Reverts if threshold is greater than number of guardians", async () => { - const signers = await ethers.getSigners(); - const accounts = signers.map(s => s.address) - - const Most = await ethers.getContractFactory("Most"); - await expect(upgrades.deployProxy(Most, - [ - [accounts[0]], - 2, - COMMISSION_PER_DIX_MILLE, - MINIMUM_TRANSFER_AMOUNT_USD, - accounts [0], - ], - { - initializer: "initialize", - kind: 'uups' - })).to.be.revertedWith("Not enough guardians specified"); - - }); + describe("Constructor", function () { + it("Reverts if threshold is 0", async () => { + const signers = await ethers.getSigners(); + const accounts = signers.map((s) => s.address); + + const Most = await ethers.getContractFactory("Most"); + await expect( + upgrades.deployProxy( + Most, + [ + [accounts[0]], + 0, + COMMISSION_PER_DIX_MILLE, + MINIMUM_TRANSFER_AMOUNT_USD, + accounts[0], + ], + { + initializer: "initialize", + kind: "uups", + }, + ), + ).to.be.revertedWith("Signature threshold must be greater than 0"); + }); + it("Reverts if threshold is greater than number of guardians", async () => { + const signers = await ethers.getSigners(); + const accounts = signers.map((s) => s.address); + + const Most = await ethers.getContractFactory("Most"); + await expect( + upgrades.deployProxy( + Most, + [ + [accounts[0]], + 2, + COMMISSION_PER_DIX_MILLE, + MINIMUM_TRANSFER_AMOUNT_USD, + accounts[0], + ], + { + initializer: "initialize", + kind: "uups", + }, + ), + ).to.be.revertedWith("Not enough guardians specified"); + }); + }); + + async function deployEightGuardianMostFixture() { + const signers = await ethers.getSigners(); + const accounts = signers.map((s) => s.address); + + const Most = await ethers.getContractFactory("Most"); + const most = await upgrades.deployProxy( + Most, + [ + accounts.slice(1, 9), + 5, + COMMISSION_PER_DIX_MILLE, + MINIMUM_TRANSFER_AMOUNT_USD, + accounts[0], + ], + { + initializer: "initialize", + kind: "uups", + }, + ); + const mostAddress = await most.getAddress(); + + const Token = await ethers.getContractFactory("Token"); + const token = await Token.deploy( + "10000000000000000000000000", + "Shittoken", + "SHIT", + ); + const tokenAddressBytes32 = addressToBytes32(await token.getAddress()); + + const usdt = await Token.deploy( + "12000000000000000000000000", + "Tether", + "USDT", + ); + const usdtAddressBytes32 = addressToBytes32(await usdt.getAddress()); + + await most.setUSDT(usdtAddressBytes32); + return { + most, + token, + tokenAddressBytes32, + usdtAddressBytes32, + mostAddress, + }; + } + + describe("sendRequest", function () { + it("Reverts if the USD value of the transfer amount is below the minimum", async () => { + const { most, tokenAddressBytes32, usdtAddressBytes32 } = + await loadFixture(deployEightGuardianMostFixture); + + await most.addPair(tokenAddressBytes32, WRAPPED_TOKEN_ADDRESS); + + amountToSend = await most.queryPrice( + MINIMUM_TRANSFER_AMOUNT_USD - 1, + usdtAddressBytes32, // of + tokenAddressBytes32, // in + ); + + await expect( + most.sendRequest(tokenAddressBytes32, amountToSend, ALEPH_ACCOUNT), + ).to.be.revertedWith("AmountBelowMinimum"); }); - async function deployEightGuardianMostFixture() { - const signers = await ethers.getSigners(); - const accounts = signers.map(s => s.address) - - const Most = await ethers.getContractFactory("Most"); - const most = await upgrades.deployProxy(Most, - [ - accounts.slice(1, 9), - 5, - COMMISSION_PER_DIX_MILLE, - MINIMUM_TRANSFER_AMOUNT_USD, - accounts [0], - ], - { - initializer: "initialize", - kind: 'uups' - }); - const mostAddress = await most.getAddress(); - - const Token = await ethers.getContractFactory("Token"); - const token = await Token.deploy("10000000000000000000000000", "Shittoken", "SHIT"); - const tokenAddressBytes32 = addressToBytes32(await token.getAddress()); - - const usdt = await Token.deploy("12000000000000000000000000", "Tether", "USDT"); - const usdtAddressBytes32 = addressToBytes32(await usdt.getAddress()); - - await most.setUSDT(usdtAddressBytes32); - return { most, token, tokenAddressBytes32, usdtAddressBytes32, mostAddress }; - } - - describe("sendRequest", function () { - it("Reverts if the USD value of the transfer amount is below the minimum", async () => { - const { most, tokenAddressBytes32, usdtAddressBytes32 } = await loadFixture(deployEightGuardianMostFixture); - - await most.addPair(tokenAddressBytes32, WRAPPED_TOKEN_ADDRESS); - - amountToSend = await most.queryPrice(MINIMUM_TRANSFER_AMOUNT_USD - 1, - usdtAddressBytes32, // of - tokenAddressBytes32 // in - ); - - await expect( - most.sendRequest( - tokenAddressBytes32, - amountToSend, - ALEPH_ACCOUNT - ) - ).to.be.revertedWith("AmountBelowMinimum"); - }); - - it("Reverts if token is not whitelisted", async () => { - const { most, token, tokenAddressBytes32, mostAddress } = await loadFixture(deployEightGuardianMostFixture); - - await token.approve(mostAddress, TOKEN_AMOUNT); - await expect( - most.sendRequest( - tokenAddressBytes32, - TOKEN_AMOUNT, - ALEPH_ACCOUNT - ) - ).to.be.revertedWith("Unsupported pair"); - }); - - it("Reverts if token transfer is not approved", async () => { - const { most, tokenAddressBytes32 } = await loadFixture(deployEightGuardianMostFixture); - - await most.addPair(tokenAddressBytes32, WRAPPED_TOKEN_ADDRESS); - await expect( - most.sendRequest( - tokenAddressBytes32, - TOKEN_AMOUNT, - ALEPH_ACCOUNT - ) - ).to.be.reverted; - }); - - it("Transfers tokens to Most", async () => { - const { most, token, tokenAddressBytes32, mostAddress } = await loadFixture(deployEightGuardianMostFixture); - - await token.approve(mostAddress, TOKEN_AMOUNT); - await most.addPair(tokenAddressBytes32, WRAPPED_TOKEN_ADDRESS); - await most.sendRequest( - tokenAddressBytes32, - TOKEN_AMOUNT, - ALEPH_ACCOUNT - ); + it("Reverts if token is not whitelisted", async () => { + const { most, token, tokenAddressBytes32, mostAddress } = + await loadFixture(deployEightGuardianMostFixture); - expect(await token.balanceOf(mostAddress)).to.equal(TOKEN_AMOUNT); - }); - - it("Emits correct event", async () => { - const { most, token, tokenAddressBytes32, mostAddress } = await loadFixture(deployEightGuardianMostFixture); - - await token.approve(mostAddress, TOKEN_AMOUNT); - await most.addPair(tokenAddressBytes32, WRAPPED_TOKEN_ADDRESS); - await expect( - most.sendRequest( - tokenAddressBytes32, - TOKEN_AMOUNT, - ALEPH_ACCOUNT - ) - ).to.emit(most, "CrosschainTransferRequest").withArgs( - 0, - WRAPPED_TOKEN_ADDRESS, - TOKEN_AMOUNT, - ALEPH_ACCOUNT, - 0, - ); - }); + await token.approve(mostAddress, TOKEN_AMOUNT); + await expect( + most.sendRequest(tokenAddressBytes32, TOKEN_AMOUNT, ALEPH_ACCOUNT), + ).to.be.revertedWith("Unsupported pair"); }); - describe("receiveRequest", function () { - it("Reverts if caller is not a guardian", async () => { - const { most, tokenAddressBytes32 } = await loadFixture(deployEightGuardianMostFixture); - const accounts = await ethers.getSigners(); - const ethAddress = addressToBytes32(accounts[10].address); - const requestHash = ethers.solidityPackedKeccak256( - ["bytes32", "uint256", "bytes32", "uint256"], - [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0] - ); + it("Reverts if token transfer is not approved", async () => { + const { most, tokenAddressBytes32 } = await loadFixture( + deployEightGuardianMostFixture, + ); - await expect( - most.connect(accounts[0]).receiveRequest( - requestHash, - tokenAddressBytes32, - TOKEN_AMOUNT, - ethAddress, - 0, - ) - ).to.be.revertedWith("NotInCommittee"); - }); - - it("Reverts if request has already been signed by a guardian", async () => { - const { most, tokenAddressBytes32 } = await loadFixture(deployEightGuardianMostFixture); - const accounts = await ethers.getSigners(); - const ethAddress = addressToBytes32(accounts[10].address); - const requestHash = ethers.solidityPackedKeccak256( - ["bytes32", "uint256", "bytes32", "uint256"], - [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0] - ); + await most.addPair(tokenAddressBytes32, WRAPPED_TOKEN_ADDRESS); + await expect( + most.sendRequest(tokenAddressBytes32, TOKEN_AMOUNT, ALEPH_ACCOUNT), + ).to.be.reverted; + }); - await most.connect(accounts[1]).receiveRequest( - requestHash, - tokenAddressBytes32, - TOKEN_AMOUNT, - ethAddress, - 0, - ); - await expect( - most.connect(accounts[1]).receiveRequest( - requestHash, - tokenAddressBytes32, - TOKEN_AMOUNT, - ethAddress, - 0, - ) - ).to.be.revertedWith("This guardian has already signed this request"); - }); - - it("Ignores already executed requests", async () => { - const { most, token, tokenAddressBytes32 } = await loadFixture(deployEightGuardianMostFixture); - const accounts = await ethers.getSigners(); - const ethAddress = addressToBytes32(accounts[10].address); - const requestHash = ethers.solidityPackedKeccak256( - ["bytes32", "uint256", "bytes32", "uint256"], - [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0] - ); + it("Transfers tokens to Most", async () => { + const { most, token, tokenAddressBytes32, mostAddress } = + await loadFixture(deployEightGuardianMostFixture); - // Provide funds for Most - await token.transfer(await most.getAddress(), TOKEN_AMOUNT * 2); - - for (let i = 1; i < 6; i++) { - await most.connect(accounts[i]).receiveRequest( - requestHash, - tokenAddressBytes32, - TOKEN_AMOUNT, - ethAddress, - 0, - ); - } + await token.approve(mostAddress, TOKEN_AMOUNT); + await most.addPair(tokenAddressBytes32, WRAPPED_TOKEN_ADDRESS); + await most.sendRequest(tokenAddressBytes32, TOKEN_AMOUNT, ALEPH_ACCOUNT); - await expect( - most.connect(accounts[6]).receiveRequest( - requestHash, - tokenAddressBytes32, - TOKEN_AMOUNT, - ethAddress, - 0, - ) - ).to.emit(most, "ProcessedRequestSigned").withArgs(requestHash, accounts[6].address); - }); - - it("Unlocks tokens for the user", async () => { - const { most, token, tokenAddressBytes32 } = await loadFixture(deployEightGuardianMostFixture); - const accounts = await ethers.getSigners(); - const ethAddress = addressToBytes32(accounts[10].address); - const requestHash = ethers.solidityPackedKeccak256( - ["bytes32", "uint256", "bytes32", "uint256"], - [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0] - ); + expect(await token.balanceOf(mostAddress)).to.equal(TOKEN_AMOUNT); + }); - // Provide funds for Most - await token.transfer(await most.getAddress(), TOKEN_AMOUNT * 2); - - for (let i = 1; i < 6; i++) { - await most.connect(accounts[i]).receiveRequest( - requestHash, - tokenAddressBytes32, - TOKEN_AMOUNT, - ethAddress, - 0, - ); - } + it("Emits correct event", async () => { + const { most, token, tokenAddressBytes32, mostAddress } = + await loadFixture(deployEightGuardianMostFixture); + + await token.approve(mostAddress, TOKEN_AMOUNT); + await most.addPair(tokenAddressBytes32, WRAPPED_TOKEN_ADDRESS); + await expect( + most.sendRequest(tokenAddressBytes32, TOKEN_AMOUNT, ALEPH_ACCOUNT), + ) + .to.emit(most, "CrosschainTransferRequest") + .withArgs(0, WRAPPED_TOKEN_ADDRESS, TOKEN_AMOUNT, ALEPH_ACCOUNT, 0); + }); + }); + + describe("receiveRequest", function () { + it("Reverts if caller is not a guardian", async () => { + const { most, tokenAddressBytes32 } = await loadFixture( + deployEightGuardianMostFixture, + ); + const accounts = await ethers.getSigners(); + const ethAddress = addressToBytes32(accounts[10].address); + const requestHash = ethers.solidityPackedKeccak256( + ["bytes32", "uint256", "bytes32", "uint256"], + [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0], + ); + + await expect( + most + .connect(accounts[0]) + .receiveRequest( + requestHash, + tokenAddressBytes32, + TOKEN_AMOUNT, + ethAddress, + 0, + ), + ).to.be.revertedWith("NotInCommittee"); + }); - expect(await token.balanceOf(accounts[10].address)).to.equal(TOKEN_AMOUNT * (DIX_MILLE - COMMISSION_PER_DIX_MILLE) / DIX_MILLE); - }); + it("Reverts if request has already been signed by a guardian", async () => { + const { most, tokenAddressBytes32 } = await loadFixture( + deployEightGuardianMostFixture, + ); + const accounts = await ethers.getSigners(); + const ethAddress = addressToBytes32(accounts[10].address); + const requestHash = ethers.solidityPackedKeccak256( + ["bytes32", "uint256", "bytes32", "uint256"], + [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0], + ); + + await most + .connect(accounts[1]) + .receiveRequest( + requestHash, + tokenAddressBytes32, + TOKEN_AMOUNT, + ethAddress, + 0, + ); + await expect( + most + .connect(accounts[1]) + .receiveRequest( + requestHash, + tokenAddressBytes32, + TOKEN_AMOUNT, + ethAddress, + 0, + ), + ).to.be.revertedWith("This guardian has already signed this request"); + }); - it("Reverts on non-matching hash", async () => { - const { most, token, tokenAddressBytes32 } = await loadFixture(deployEightGuardianMostFixture); - const accounts = await ethers.getSigners(); - const ethAddress = addressToBytes32(accounts[10].address); - const requestHash = ethers.solidityPackedKeccak256( - ["bytes32", "uint256", "bytes32", "uint256"], - [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 1] - ); + it("Ignores already executed requests", async () => { + const { most, token, tokenAddressBytes32 } = await loadFixture( + deployEightGuardianMostFixture, + ); + const accounts = await ethers.getSigners(); + const ethAddress = addressToBytes32(accounts[10].address); + const requestHash = ethers.solidityPackedKeccak256( + ["bytes32", "uint256", "bytes32", "uint256"], + [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0], + ); + + // Provide funds for Most + await token.transfer(await most.getAddress(), TOKEN_AMOUNT * 2); + + for (let i = 1; i < 6; i++) { + await most + .connect(accounts[i]) + .receiveRequest( + requestHash, + tokenAddressBytes32, + TOKEN_AMOUNT, + ethAddress, + 0, + ); + } + + await expect( + most + .connect(accounts[6]) + .receiveRequest( + requestHash, + tokenAddressBytes32, + TOKEN_AMOUNT, + ethAddress, + 0, + ), + ) + .to.emit(most, "ProcessedRequestSigned") + .withArgs(requestHash, accounts[6].address); + }); - // Provide funds for Most - await token.transfer(await most.getAddress(), TOKEN_AMOUNT * 2); - - await expect( - most.connect(accounts[1]).receiveRequest( - requestHash, - tokenAddressBytes32, - TOKEN_AMOUNT, - ethAddress, - 0, - ) - ).to.be.revertedWith("Hash does not match the data"); - }); + it("Unlocks tokens for the user", async () => { + const { most, token, tokenAddressBytes32 } = await loadFixture( + deployEightGuardianMostFixture, + ); + const accounts = await ethers.getSigners(); + const ethAddress = addressToBytes32(accounts[10].address); + const requestHash = ethers.solidityPackedKeccak256( + ["bytes32", "uint256", "bytes32", "uint256"], + [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0], + ); + + // Provide funds for Most + await token.transfer(await most.getAddress(), TOKEN_AMOUNT * 2); + + for (let i = 1; i < 6; i++) { + await most + .connect(accounts[i]) + .receiveRequest( + requestHash, + tokenAddressBytes32, + TOKEN_AMOUNT, + ethAddress, + 0, + ); + } + + expect(await token.balanceOf(accounts[10].address)).to.equal( + (TOKEN_AMOUNT * (DIX_MILLE - COMMISSION_PER_DIX_MILLE)) / DIX_MILLE, + ); }); - describe("payoutRewards", function () { - it("account can request a payout", async () => { - const { most, token, tokenAddressBytes32 } = await loadFixture(deployEightGuardianMostFixture); - const accounts = await ethers.getSigners(); - const ethAddress = addressToBytes32(accounts[10].address); - const requestHash = ethers.solidityPackedKeccak256( - ["bytes32", "uint256", "bytes32", "uint256"], - [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0] - ); + it("Reverts on non-matching hash", async () => { + const { most, token, tokenAddressBytes32 } = await loadFixture( + deployEightGuardianMostFixture, + ); + const accounts = await ethers.getSigners(); + const ethAddress = addressToBytes32(accounts[10].address); + const requestHash = ethers.solidityPackedKeccak256( + ["bytes32", "uint256", "bytes32", "uint256"], + [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 1], + ); + + // Provide funds for Most + await token.transfer(await most.getAddress(), TOKEN_AMOUNT * 2); + + await expect( + most + .connect(accounts[1]) + .receiveRequest( + requestHash, + tokenAddressBytes32, + TOKEN_AMOUNT, + ethAddress, + 0, + ), + ).to.be.revertedWith("Hash does not match the data"); + }); + }); + + describe("payoutRewards", function () { + it("account can request a payout", async () => { + const { most, token, tokenAddressBytes32 } = await loadFixture( + deployEightGuardianMostFixture, + ); + const accounts = await ethers.getSigners(); + const ethAddress = addressToBytes32(accounts[10].address); + const requestHash = ethers.solidityPackedKeccak256( + ["bytes32", "uint256", "bytes32", "uint256"], + [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0], + ); + + // Provide funds for Most + await token.transfer(await most.getAddress(), TOKEN_AMOUNT * 2); + + for (let i = 1; i < 6; i++) { + await most + .connect(accounts[i]) + .receiveRequest( + requestHash, + tokenAddressBytes32, + TOKEN_AMOUNT, + ethAddress, + 0, + ); + } + + currentCommitteeId = await most.committeeId(); + totalRewards = await most.getCollectedCommitteeRewards( + currentCommitteeId, + tokenAddressBytes32, + ); + + await expect(currentCommitteeId).to.be.equal(0); + + signerBalanceBefore = await token.balanceOf(accounts[1].address); + + await most.payoutRewards( + currentCommitteeId, + accounts[1].address, + tokenAddressBytes32, + ); + + signerBalanceAfter = await token.balanceOf(accounts[1].address); + await expect(signerBalanceAfter).to.be.equal( + signerBalanceBefore + totalRewards / BigInt(8), + ); + }); - // Provide funds for Most - await token.transfer(await most.getAddress(), TOKEN_AMOUNT * 2); - - for (let i = 1; i < 6 ; i++) { - await most.connect(accounts[i]).receiveRequest( - requestHash, - tokenAddressBytes32, - TOKEN_AMOUNT, - ethAddress, - 0, - ); + it("past committee member can still request a payout", async () => { + const { most, token, tokenAddressBytes32 } = await loadFixture( + deployEightGuardianMostFixture, + ); + const accounts = await ethers.getSigners(); + const ethAddress = addressToBytes32(accounts[10].address); + const requestHash = ethers.solidityPackedKeccak256( + ["bytes32", "uint256", "bytes32", "uint256"], + [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0], + ); + + // Provide funds for Most + await token.transfer(await most.getAddress(), TOKEN_AMOUNT * 2); + + for (let i = 1; i < 6; i++) { + await most + .connect(accounts[i]) + .receiveRequest( + requestHash, + tokenAddressBytes32, + TOKEN_AMOUNT, + ethAddress, + 0, + ); + } + + previousCommitteeId = await most.committeeId(); + + await expect(previousCommitteeId).to.be.equal(0); + + let committee = accounts.slice(2, 9).map((x) => x.address); + let threshold = 4; + + await most.setCommittee(committee, threshold); + + await expect(await most.committeeId()).to.be.equal(1); + + totalRewards = await most.getCollectedCommitteeRewards( + previousCommitteeId, + tokenAddressBytes32, + ); + signerBalanceBefore = await token.balanceOf(accounts[1].address); + + await most.payoutRewards( + previousCommitteeId, + accounts[1].address, + tokenAddressBytes32, + ); + + signerBalanceAfter = await token.balanceOf(accounts[1].address); + await expect(signerBalanceAfter).to.be.equal( + signerBalanceBefore + totalRewards / BigInt(8), + ); + }); + }); + + describe("Upgrade", function () { + it("Most contract can be upgraded", async () => { + exec("cp ./contracts/Most.sol ./contracts/MostV2.sol", (error) => { + if (error !== null) { + console.log("exec error: " + error); + } + exec( + 'sed -i "17 a uint256 public test;" ./contracts/MostV2.sol', + async (error, stdout, stderr) => { + if (error !== null) { + console.log("exec error: " + error); } - currentCommitteeId = await most.committeeId (); - totalRewards = await most.getCollectedCommitteeRewards (currentCommitteeId, tokenAddressBytes32); - - await expect( - currentCommitteeId - ).to.be.equal(0); - - signerBalanceBefore = await token.balanceOf(accounts[1].address); - - await most.payoutRewards (currentCommitteeId, - accounts[1].address, - tokenAddressBytes32); - - signerBalanceAfter = await token.balanceOf(accounts[1].address); - await expect(signerBalanceAfter).to.be.equal(signerBalanceBefore + (totalRewards / BigInt (8))); - }); - - it("past committee member can still request a payout", async () => { - const { most, token, tokenAddressBytes32 } = await loadFixture(deployEightGuardianMostFixture); - const accounts = await ethers.getSigners(); - const ethAddress = addressToBytes32(accounts[10].address); - const requestHash = ethers.solidityPackedKeccak256( - ["bytes32", "uint256", "bytes32", "uint256"], - [tokenAddressBytes32, TOKEN_AMOUNT, ethAddress, 0] + const { most, mostAddress } = await loadFixture( + deployEightGuardianMostFixture, ); - // Provide funds for Most - await token.transfer(await most.getAddress(), TOKEN_AMOUNT * 2); - - for (let i = 1; i < 6 ; i++) { - await most.connect(accounts[i]).receiveRequest( - requestHash, - tokenAddressBytes32, - TOKEN_AMOUNT, - ethAddress, - 0, - ); - } - - previousCommitteeId = await most.committeeId (); - - await expect( - previousCommitteeId - ).to.be.equal(0); - + const accounts = await ethers.getSigners(); let committee = accounts.slice(2, 9).map((x) => x.address); let threshold = 4; - - await most.setCommittee (committee, threshold); - - await expect( - await most.committeeId () - ).to.be.equal(1); - - totalRewards = await most.getCollectedCommitteeRewards (previousCommitteeId, tokenAddressBytes32); - signerBalanceBefore = await token.balanceOf(accounts[1].address); - - await most.payoutRewards (previousCommitteeId, - accounts[1].address, - tokenAddressBytes32); - - signerBalanceAfter = await token.balanceOf(accounts[1].address); - await expect(signerBalanceAfter).to.be.equal(signerBalanceBefore + (totalRewards / BigInt (8))); - }); + await most.setCommittee(committee, threshold); + + const MostV2 = await ethers.getContractFactory("MostV2"); + const mostV2 = await upgrades.upgradeProxy(mostAddress, MostV2); + + const address = await mostV2.getAddress(); + // address is preserved + expect(address).to.be.equal(mostAddress); + + // state is preserved + expect(most.isInCommittee(committee[0])); + + // no state overwrite + expect(most.test()).to.be.equal(0); + }, + ); + }); + + // clean up + exec("rm ./contracts/MostV2.sol", (error, stdout, stderr) => { + if (error !== null) { + console.log("exec error: " + error); + } + }); }); - - describe("Upgrade", function () { - it("Most contract can be upgraded", async () => { - exec('cp ./contracts/Most.sol ./contracts/MostV2.sol', - (error) => { - if (error !== null) { - console.log('exec error: ' + error); - } - exec('sed -i "17 a \ \ \ \ uint256 public test;" ./contracts/MostV2.sol', - async (error, stdout, stderr) => { - if (error !== null) { - console.log('exec error: ' + error); - } - - const { most, mostAddress } = await loadFixture(deployEightGuardianMostFixture); - - const accounts = await ethers.getSigners(); - let committee = accounts.slice(2, 9).map((x) => x.address); - let threshold = 4; - await most.setCommittee (committee, threshold); - - const MostV2 = await ethers.getContractFactory("MostV2"); - const mostV2 = await upgrades.upgradeProxy(mostAddress, MostV2); - - const address = await mostV2.getAddress(); - // address is preserved - expect(address).to.be.equal(mostAddress); - - // state is preserved - expect((most.isInCommittee(committee[0]))); - - // no state overwrite - expect((most.test())).to.be.equal(0); - - }); - }); - - // clean up - exec('rm ./contracts/MostV2.sol', - (error, stdout, stderr) => { - if (error !== null) { - console.log('exec error: ' + error); - } - }); - }); - }); - + }); }); diff --git a/relayer/src/contracts/eth.rs b/relayer/src/contracts/eth.rs index f674f8f9..16b0ac59 100644 --- a/relayer/src/contracts/eth.rs +++ b/relayer/src/contracts/eth.rs @@ -1,6 +1,3 @@ use ethers::contract::abigen; -abigen!( - Most, - "../eth/artifacts/contracts/Most.sol/Most.json" -); +abigen!(Most, "../eth/artifacts/contracts/Most.sol/Most.json"); diff --git a/relayer/src/listeners/azero.rs b/relayer/src/listeners/azero.rs index 803f9586..d9a01ed2 100644 --- a/relayer/src/listeners/azero.rs +++ b/relayer/src/listeners/azero.rs @@ -110,8 +110,7 @@ impl AlephZeroListener { let event_handler_tasks_semaphore = Arc::new(Semaphore::new(*azero_max_event_handler_tasks)); - let most_instance = - MostInstance::new(azero_contract_address, azero_contract_metadata)?; + let most_instance = MostInstance::new(azero_contract_address, azero_contract_metadata)?; let mut first_unprocessed_block_number = read_first_unprocessed_block_number( name.clone(), ALEPH_LAST_BLOCK_KEY.to_string(), diff --git a/relayer/src/listeners/eth.rs b/relayer/src/listeners/eth.rs index 10db8281..0ae44a26 100644 --- a/relayer/src/listeners/eth.rs +++ b/relayer/src/listeners/eth.rs @@ -25,8 +25,7 @@ use crate::{ redis_helpers::{read_first_unprocessed_block_number, write_last_processed_block}, }, contracts::{ - AzeroContractError, CrosschainTransferRequestFilter, Most, MostEvents, - MostInstance, + AzeroContractError, CrosschainTransferRequestFilter, Most, MostEvents, MostInstance, }, helpers::concat_u8_arrays, };