From 7912b2c32029f9c98ba1589dfd093cb9a1ee9c0b Mon Sep 17 00:00:00 2001 From: "max.hayes" Date: Thu, 8 Dec 2022 14:15:46 +0400 Subject: [PATCH 01/77] Mainnet deployment requirements 1 --- scripts/migrations/deployment/1_deploy_vToken.js | 4 ++-- scripts/migrations/deployment/4_deploy_main_token.js | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/migrations/deployment/1_deploy_vToken.js b/scripts/migrations/deployment/1_deploy_vToken.js index 80952c4..b0615ee 100644 --- a/scripts/migrations/deployment/1_deploy_vToken.js +++ b/scripts/migrations/deployment/1_deploy_vToken.js @@ -1,8 +1,8 @@ const VMainToken = artifacts.require('./dao/tokens/VMainToken.sol'); const vMainToken = { - name: "Vote Fathom", - symbol: "vFTHM" + name: "Fathom Protocol Vote Token", + symbol: "VFTHM" }; module.exports = async function(deployer) { diff --git a/scripts/migrations/deployment/4_deploy_main_token.js b/scripts/migrations/deployment/4_deploy_main_token.js index 38021f3..44e9b2c 100644 --- a/scripts/migrations/deployment/4_deploy_main_token.js +++ b/scripts/migrations/deployment/4_deploy_main_token.js @@ -2,9 +2,9 @@ const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); const mainToken = { - name: "Fathom", + name: "Fathom Protocol Token", symbol: "FTHM", - totalSupply: web3.utils.toWei("1000000", "ether"), + totalSupply: web3.utils.toWei("1000000000000000000000000000", "wei"), issuer: MultiSigWallet.address }; From 994bc71220603367c968351c0e06be29996ce756 Mon Sep 17 00:00:00 2001 From: "max.hayes" Date: Thu, 8 Dec 2022 14:36:59 +0400 Subject: [PATCH 02/77] Mainnet deployment requirements 2 --- scripts/migrations/deployment/5_deploy_governor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/migrations/deployment/5_deploy_governor.js b/scripts/migrations/deployment/5_deploy_governor.js index adae8f3..63b03fa 100644 --- a/scripts/migrations/deployment/5_deploy_governor.js +++ b/scripts/migrations/deployment/5_deploy_governor.js @@ -6,8 +6,8 @@ const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const VMainToken_address = VMainToken.address; const TimelockController_address = TimelockController.address; const MultiSigWallet_address = MultiSigWallet.address; -const initialVotingDelay = 1; -const votingPeriod = 20; +const initialVotingDelay = 43200; +const votingPeriod = 43200 * 5; const initialProposalThreshold = 1000; From fb9a638acf7cd8bdb09c10d3ca0f0cadccadcea2 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 8 Dec 2022 17:00:46 +0545 Subject: [PATCH 03/77] changes for staking for release --- .../prod/1_deploy_init_staking_proxy.js | 17 ++++++++--------- .../migrations/prod/5_setup_council_stakes.js | 6 +++--- scripts/migrations/prod/6_setup_vault_tokens.js | 2 +- 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index c4ace07..32af970 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -46,6 +46,7 @@ const _getTimeStamp = async () => { const vMainTokenCoefficient = 500; const oneYear = 31556926; +const oneDay = 24 * 60 * 60; const maxWeightShares = 1024; const minWeightShares = 768; @@ -71,21 +72,19 @@ module.exports = async function(deployer) { ); - const startTime = await _getTimeStamp() + 3 * 24 * 60 * 60; + const startTime = await _getTimeStamp() + 60 * 60; const scheduleTimes = [ startTime, - startTime + oneYear, - startTime + 2 * oneYear, - startTime + 3 * oneYear, - startTime + 4 * oneYear, + startTime + oneDay, + startTime + 2 * oneDay, + startTime + 3 * oneDay ]; const scheduleRewards = [ - web3.utils.toWei('20000', 'ether'), - web3.utils.toWei('10000', 'ether'), - web3.utils.toWei('5000', 'ether'), - web3.utils.toWei('2500', 'ether'), + web3.utils.toWei('150000000', 'ether'), + web3.utils.toWei('100000000', 'ether'), + web3.utils.toWei('50000000', 'ether'), web3.utils.toWei("0", 'ether') ]; diff --git a/scripts/migrations/prod/5_setup_council_stakes.js b/scripts/migrations/prod/5_setup_council_stakes.js index 342451c..ae19748 100644 --- a/scripts/migrations/prod/5_setup_council_stakes.js +++ b/scripts/migrations/prod/5_setup_council_stakes.js @@ -11,10 +11,10 @@ const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWa const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const LOCK_PERIOD = 365 * 24 * 60 * 60; +const LOCK_PERIOD = 4 * 24 * 60 * 60 -const T_TO_TRANSFER = web3.utils.toWei('150000', 'ether'); -const T_TO_STAKE = web3.utils.toWei('50000', 'ether'); +const T_TO_TRANSFER = web3.utils.toWei('150000000', 'ether'); +const T_TO_STAKE = web3.utils.toWei('50000000', 'ether'); const COUNCIL_1 = "0xc0Ee98ac1a44B56fbe2669A3B3C006DEB6fDd0f9"; const COUNCIL_2 = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; diff --git a/scripts/migrations/prod/6_setup_vault_tokens.js b/scripts/migrations/prod/6_setup_vault_tokens.js index 43edf83..92f2d6b 100644 --- a/scripts/migrations/prod/6_setup_vault_tokens.js +++ b/scripts/migrations/prod/6_setup_vault_tokens.js @@ -9,7 +9,7 @@ const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWa const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const T_TO_TRANSFER = web3.utils.toWei('20000', 'ether'); +const T_TO_TRANSFER = web3.utils.toWei('150000000', 'ether'); const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') From dd1f5826940d1073f5a52d79da36cf9aec507d4d Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 8 Dec 2022 17:36:40 +0545 Subject: [PATCH 04/77] timestamp added --- scripts/migrations/prod/1_deploy_init_staking_proxy.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index 32af970..ee5a4d5 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -43,7 +43,7 @@ const _getTimeStamp = async () => { return timestamp; } - const vMainTokenCoefficient = 500; +const vMainTokenCoefficient = 500; const oneYear = 31556926; const oneDay = 24 * 60 * 60; @@ -71,8 +71,9 @@ module.exports = async function(deployer) { weightMultiplier ); + const thirteenDecemberTimestampMidNight = 1670889600 - const startTime = await _getTimeStamp() + 60 * 60; + const startTime = thirteenDecemberTimestampMidNight; const scheduleTimes = [ startTime, From b9e4f4d8b387f3b89c394b0078f6dbc4be54e95d Mon Sep 17 00:00:00 2001 From: ssubik Date: Fri, 9 Dec 2022 21:52:49 +0545 Subject: [PATCH 05/77] addresses --- coralX-scenarios.js | 12 ++++++--- .../prod/1_deploy_init_staking_proxy.js | 4 +-- .../migrations/prod/5_setup_council_stakes.js | 2 +- ...ddress.js => 1_save_address_deployment.js} | 11 -------- .../save-address/2_save_address_setup.js | 25 +++++++++++++++++ .../save-address/3_save_address_prod.js | 27 +++++++++++++++++++ 6 files changed, 64 insertions(+), 17 deletions(-) rename scripts/migrations/save-address/{1_save_address.js => 1_save_address_deployment.js} (67%) create mode 100644 scripts/migrations/save-address/2_save_address_setup.js create mode 100644 scripts/migrations/save-address/3_save_address_prod.js diff --git a/coralX-scenarios.js b/coralX-scenarios.js index 4d35493..56dc312 100644 --- a/coralX-scenarios.js +++ b/coralX-scenarios.js @@ -7,23 +7,29 @@ module.exports = { ], deployApothem: [ ['execute', '--path', 'scripts/migrations/deployment', '--network', 'apothem'], + ['execute', '--path', 'scripts/migrations/save-address/1_save_address_deployment.js', '--network', 'apothem'], ['execute', '--path', 'scripts/migrations/setup', '--network', 'apothem'], + ['execute', '--path', 'scripts/migrations/save-address/2_save_address_setup.js', '--network', 'apothem'], ['execute', '--path', 'scripts/migrations/prod', '--network', 'apothem'], - ['execute', '--path', 'scripts/migrations/save-address', '--network', 'apothem'] + ['execute', '--path', 'scripts/migrations/save-address/3_save_address_prod.js', '--network', 'apothem'] ], deployXDC: [ ['execute', '--path', 'scripts/migrations/deployment', '--network', 'xdc'], + ['execute', '--path', 'scripts/migrations/save-address/1_save_address_deployment.js', '--network', 'xdc'], ['execute', '--path', 'scripts/migrations/setup', '--network', 'xdc'], + ['execute', '--path', 'scripts/migrations/save-address/2_save_address_setup.js', '--network', 'xdc'], ['execute', '--path', 'scripts/migrations/prod', '--network', 'xdc'], - ['execute', '--path', 'scripts/migrations/save-address', '--network', 'xdc'] + ['execute', '--path', 'scripts/migrations/save-address/3_save_address_prod.js', '--network', 'xdc'] ], migrateAndConfigureForTests: [ ['compile'], ['execute', '--path', 'scripts/migrations/deployment'], + ['execute', '--path', 'scripts/migrations/save-address/1_save_address_deployment.js'], ['execute', '--path', 'scripts/migrations/setup'], + ['execute', '--path', 'scripts/migrations/save-address/2_save_address_setup.js'], ['execute', '--path', 'scripts/migrations/test'], + ['execute', '--path', 'scripts/migrations/save-address/3_save_address_prod.js'], ['execute', '--path', 'scripts/migrations/upgrades'], - ['execute', '--path', 'scripts/migrations/save-address'], ], createStablecoinPool: [ ['execute', '--path', 'scripts/stablecoin-integration/create-pool-through-governance.js'] diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index ee5a4d5..62598ec 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -46,7 +46,7 @@ const _getTimeStamp = async () => { const vMainTokenCoefficient = 500; const oneYear = 31556926; -const oneDay = 24 * 60 * 60; +const oneDay = 86400; const maxWeightShares = 1024; const minWeightShares = 768; @@ -57,7 +57,7 @@ const maxNumberOfLocks = 10; const tau = 2; -const lockingVoteWeight = 365 * 24 * 60 * 60; +const lockingVoteWeight = 31556926; module.exports = async function(deployer) { try{ diff --git a/scripts/migrations/prod/5_setup_council_stakes.js b/scripts/migrations/prod/5_setup_council_stakes.js index ae19748..bb0781d 100644 --- a/scripts/migrations/prod/5_setup_council_stakes.js +++ b/scripts/migrations/prod/5_setup_council_stakes.js @@ -11,7 +11,7 @@ const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWa const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const LOCK_PERIOD = 4 * 24 * 60 * 60 +const LOCK_PERIOD = 345600 const T_TO_TRANSFER = web3.utils.toWei('150000000', 'ether'); const T_TO_STAKE = web3.utils.toWei('50000000', 'ether'); diff --git a/scripts/migrations/save-address/1_save_address.js b/scripts/migrations/save-address/1_save_address_deployment.js similarity index 67% rename from scripts/migrations/save-address/1_save_address.js rename to scripts/migrations/save-address/1_save_address_deployment.js index bf16f22..ba48ad9 100644 --- a/scripts/migrations/save-address/1_save_address.js +++ b/scripts/migrations/save-address/1_save_address_deployment.js @@ -6,11 +6,6 @@ const MainTokenGovernor = artifacts.require('./dao/governance/MainTokenGovernor. const PackageStaking = artifacts.require('./dao/staking/packages/StakingPackage.sol'); const VaultPackage = artifacts.require('./dao/staking/vault/packages/VaultPackage.sol'); const RewardsCalculator = artifacts.require('./dao/staking/packages/RewardsCalculator.sol'); -const StakingProxyAdmin = artifacts.require('./common/proxy/StakingProxyAdmin.sol'); -const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') -const VaultProxyAdmin = artifacts.require('./common/proxy/VaultProxyAdmin.sol'); -const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') -const StakingGettersHelper = artifacts.require('./dao/staking/helpers/StakingGettersHelper.sol') const fs = require('fs') module.exports = async function(deployer) { let addresses = { @@ -22,11 +17,6 @@ module.exports = async function(deployer) { stakingImplementation: PackageStaking.address, vaultImplementation: VaultPackage.address, rewardsCalculator: RewardsCalculator.address, - stakingProxyAdmin: StakingProxyAdmin.address, - staking: StakingProxy.address, - vaultProxyAdmin: VaultProxyAdmin.address, - vault: VaultProxy.address, - stakingGetter: StakingGettersHelper.address } let data = JSON.stringify(addresses); @@ -35,5 +25,4 @@ module.exports = async function(deployer) { console.log(err) } }) - } \ No newline at end of file diff --git a/scripts/migrations/save-address/2_save_address_setup.js b/scripts/migrations/save-address/2_save_address_setup.js new file mode 100644 index 0000000..5ae96b3 --- /dev/null +++ b/scripts/migrations/save-address/2_save_address_setup.js @@ -0,0 +1,25 @@ +const VaultProxyAdmin = artifacts.require('./common/proxy/VaultProxyAdmin.sol'); +const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') +const fs = require('fs') +const rawdata = fs.readFileSync('../../../build/build_system_addresses.json'); +let daoAddress = JSON.parse(rawdata) +module.exports = async function(deployer) { + let addresses = { + vaultProxyAdmin: VaultProxyAdmin.address, + vault: VaultProxy.address, + } + + const newAddresses = { + ...daoAddress, + ...addresses + } + + + let data = JSON.stringify(newAddresses); + fs.writeFileSync('./build/build_system_addresses.json',data, function(err){ + if(err){ + console.log(err) + } + }) + +} \ No newline at end of file diff --git a/scripts/migrations/save-address/3_save_address_prod.js b/scripts/migrations/save-address/3_save_address_prod.js new file mode 100644 index 0000000..51d604a --- /dev/null +++ b/scripts/migrations/save-address/3_save_address_prod.js @@ -0,0 +1,27 @@ +const StakingProxyAdmin = artifacts.require('./common/proxy/StakingProxyAdmin.sol'); +const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') +const StakingGettersHelper = artifacts.require('./dao/staking/helpers/StakingGettersHelper.sol') +const fs = require('fs') +const rawdata = fs.readFileSync('../../../build/build_system_addresses.json'); +let daoAddress = JSON.parse(rawdata) +module.exports = async function(deployer) { + let addresses = { + stakingProxyAdmin: StakingProxyAdmin.address, + staking: StakingProxy.address, + stakingGetter: StakingGettersHelper.address + } + + const newAddresses = { + ...daoAddress, + ...addresses + } + + + let data = JSON.stringify(newAddresses); + fs.writeFileSync('./build/build_system_addresses.json',data, function(err){ + if(err){ + console.log(err) + } + }) + +} \ No newline at end of file From 5011670b4bc667519a65b7df4929f6c62e7bd004 Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 12 Dec 2022 13:41:13 +0545 Subject: [PATCH 06/77] changing rewards --- scripts/migrations/deployment/5_deploy_governor.js | 4 ++-- scripts/migrations/prod/1_deploy_init_staking_proxy.js | 6 ++---- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/scripts/migrations/deployment/5_deploy_governor.js b/scripts/migrations/deployment/5_deploy_governor.js index 63b03fa..2d07e5a 100644 --- a/scripts/migrations/deployment/5_deploy_governor.js +++ b/scripts/migrations/deployment/5_deploy_governor.js @@ -6,8 +6,8 @@ const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const VMainToken_address = VMainToken.address; const TimelockController_address = TimelockController.address; const MultiSigWallet_address = MultiSigWallet.address; -const initialVotingDelay = 43200; -const votingPeriod = 43200 * 5; +const initialVotingDelay = 1 * 60 / 2; +const votingPeriod = 60 * 15 / 2; const initialProposalThreshold = 1000; diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index 62598ec..1a0ab31 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -78,14 +78,12 @@ module.exports = async function(deployer) { const scheduleTimes = [ startTime, startTime + oneDay, - startTime + 2 * oneDay, - startTime + 3 * oneDay + startTime + 36 * oneDay, ]; const scheduleRewards = [ web3.utils.toWei('150000000', 'ether'), - web3.utils.toWei('100000000', 'ether'), - web3.utils.toWei('50000000', 'ether'), + web3.utils.toWei('140000000', 'ether'), web3.utils.toWei("0", 'ether') ]; From 220503428c8e699c0b15e6fec40d644cee09882e Mon Sep 17 00:00:00 2001 From: maaxnaax Date: Mon, 12 Dec 2022 11:58:51 +0400 Subject: [PATCH 07/77] Updated Governance requirements --- scripts/migrations/deployment/5_deploy_governor.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/migrations/deployment/5_deploy_governor.js b/scripts/migrations/deployment/5_deploy_governor.js index 63b03fa..e1535a9 100644 --- a/scripts/migrations/deployment/5_deploy_governor.js +++ b/scripts/migrations/deployment/5_deploy_governor.js @@ -6,8 +6,8 @@ const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const VMainToken_address = VMainToken.address; const TimelockController_address = TimelockController.address; const MultiSigWallet_address = MultiSigWallet.address; -const initialVotingDelay = 43200; -const votingPeriod = 43200 * 5; +const initialVotingDelay = 30; +const votingPeriod = 450; const initialProposalThreshold = 1000; From 519c1748a5af2843a2f5b701fd3fd38147b914ae Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 12 Dec 2022 20:08:35 +0545 Subject: [PATCH 08/77] changed scripts params --- .../prod/1_deploy_init_staking_proxy.js | 73 ++++++++++++++++++- .../migrations/prod/5_setup_council_stakes.js | 2 +- .../setup/1_init_timelock_controller.js | 2 +- 3 files changed, 73 insertions(+), 4 deletions(-) diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index 1a0ab31..490174e 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -55,7 +55,7 @@ const minWeightPenalty = 100; const weightMultiplier = 10; const maxNumberOfLocks = 10; -const tau = 2; +const tau = 60; const lockingVoteWeight = 31556926; @@ -77,13 +77,82 @@ module.exports = async function(deployer) { const scheduleTimes = [ startTime, - startTime + oneDay, + startTime + 1 * oneDay, + startTime + 2 * oneDay, + startTime + 3 * oneDay, + startTime + 4 * oneDay, + startTime + 5 * oneDay, + startTime + 6 * oneDay, + startTime + 7 * oneDay, + startTime + 8 * oneDay, + startTime + 9 * oneDay, + startTime + 10 * oneDay, + startTime + 11 * oneDay, + startTime + 12 * oneDay, + startTime + 13 * oneDay, + startTime + 14 * oneDay, + startTime + 15 * oneDay, + startTime + 16 * oneDay, + startTime + 17 * oneDay, + startTime + 18 * oneDay, + startTime + 19 * oneDay, + startTime + 20 * oneDay, + startTime + 21 * oneDay, + startTime + 22 * oneDay, + startTime + 23 * oneDay, + startTime + 24 * oneDay, + startTime + 25 * oneDay, + startTime + 26 * oneDay, + startTime + 27 * oneDay, + startTime + 28 * oneDay, + startTime + 29 * oneDay, + startTime + 30 * oneDay, + startTime + 31 * oneDay, + startTime + 32 * oneDay, + startTime + 33 * oneDay, + startTime + 34 * oneDay, + startTime + 35 * oneDay, startTime + 36 * oneDay, ]; + const scheduleRewards = [ web3.utils.toWei('150000000', 'ether'), web3.utils.toWei('140000000', 'ether'), + web3.utils.toWei('136000000', 'ether'), + web3.utils.toWei('132000000', 'ether'), + web3.utils.toWei('128000000', 'ether'), + web3.utils.toWei('124000000', 'ether'), + web3.utils.toWei('120000000', 'ether'), + web3.utils.toWei('116000000', 'ether'), + web3.utils.toWei('112000000', 'ether'), + web3.utils.toWei('108000000', 'ether'), + web3.utils.toWei('104000000', 'ether'), + web3.utils.toWei('100000000', 'ether'), + web3.utils.toWei('96000000', 'ether'), + web3.utils.toWei('92000000', 'ether'), + web3.utils.toWei('88000000', 'ether'), + web3.utils.toWei('84000000', 'ether'), + web3.utils.toWei('80000000', 'ether'), + web3.utils.toWei('76000000', 'ether'), + web3.utils.toWei('72000000', 'ether'), + web3.utils.toWei('68000000', 'ether'), + web3.utils.toWei('64000000', 'ether'), + web3.utils.toWei('60000000', 'ether'), + web3.utils.toWei('56000000', 'ether'), + web3.utils.toWei('52000000', 'ether'), + web3.utils.toWei('48000000', 'ether'), + web3.utils.toWei('44000000', 'ether'), + web3.utils.toWei('40000000', 'ether'), + web3.utils.toWei('36000000', 'ether'), + web3.utils.toWei('32000000', 'ether'), + web3.utils.toWei('28000000', 'ether'), + web3.utils.toWei('24000000', 'ether'), + web3.utils.toWei('20000000', 'ether'), + web3.utils.toWei('16000000', 'ether'), + web3.utils.toWei('12000000', 'ether'), + web3.utils.toWei('8000000', 'ether'), + web3.utils.toWei('4000000', 'ether'), web3.utils.toWei("0", 'ether') ]; diff --git a/scripts/migrations/prod/5_setup_council_stakes.js b/scripts/migrations/prod/5_setup_council_stakes.js index bb0781d..4feb20e 100644 --- a/scripts/migrations/prod/5_setup_council_stakes.js +++ b/scripts/migrations/prod/5_setup_council_stakes.js @@ -11,7 +11,7 @@ const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWa const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const LOCK_PERIOD = 345600 +const LOCK_PERIOD = 259200 //3 days const T_TO_TRANSFER = web3.utils.toWei('150000000', 'ether'); const T_TO_STAKE = web3.utils.toWei('50000000', 'ether'); diff --git a/scripts/migrations/setup/1_init_timelock_controller.js b/scripts/migrations/setup/1_init_timelock_controller.js index d3e0e48..79887c4 100644 --- a/scripts/migrations/setup/1_init_timelock_controller.js +++ b/scripts/migrations/setup/1_init_timelock_controller.js @@ -6,7 +6,7 @@ const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); // interfaces const ITimelockController = artifacts.require('./dao/governance/interfaces/ITimelockController.sol'); -const minDelay = 1; +const minDelay = 30; const proposers = [MainTokenGovernor.address]; const executors = [MainTokenGovernor.address]; From a9b8ed8fe5e8d2db84b3abca44ec80b6e2c01d77 Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 12 Dec 2022 20:12:49 +0545 Subject: [PATCH 09/77] changed timestamp --- scripts/migrations/prod/1_deploy_init_staking_proxy.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index 490174e..096151a 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -71,9 +71,10 @@ module.exports = async function(deployer) { weightMultiplier ); - const thirteenDecemberTimestampMidNight = 1670889600 - - const startTime = thirteenDecemberTimestampMidNight; + // const thirteenDecemberTimestampMidNight = 1670889600 + const EightThirtyPMUAETimestampTwelveDec = 1670862600; + + const startTime = EightThirtyPMUAETimestampTwelveDec; const scheduleTimes = [ startTime, From ddc110e7d710ea8e04a01a12592ffb4a38115998 Mon Sep 17 00:00:00 2001 From: maaxnaax Date: Wed, 14 Dec 2022 16:03:55 +0400 Subject: [PATCH 10/77] Update Governor.sol --- contracts/dao/governance/Governor.sol | 1 + 1 file changed, 1 insertion(+) diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 54afae0..ca9b9ed 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -403,6 +403,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); uint256 weight = _getVotes(account, proposal.voteStart.getDeadline(), params); + require(weight>0, "vFTHM balance is 0"); _countVote(proposalId, account, support, weight, params); if (params.length == 0) { From fb59561335bde3c0bc51330412ea1c8f728f839e Mon Sep 17 00:00:00 2001 From: ssubik Date: Tue, 27 Dec 2022 13:23:01 +0545 Subject: [PATCH 11/77] audit-fixes and rebasing --- audit-report/Fathom DAO.pdf | Bin 0 -> 1265693 bytes audit-report/Fathom_DAO.md | 1048 +++++++++++++++++ contracts/common/Address.sol | 8 + contracts/dao/governance/Governor.sol | 22 +- .../dao/governance/TimelockController.sol | 2 + .../extensions/GovernorSettings.sol | 1 + .../extensions/GovernorTimelockControl.sol | 1 + .../GovernorVotesQuorumFraction.sol | 4 +- contracts/dao/staking/StakingStorage.sol | 2 + .../staking/interfaces/IStakingHandler.sol | 9 - .../staking/interfaces/IStakingStorage.sol | 2 + .../dao/staking/packages/RewardsInternals.sol | 1 + .../dao/staking/packages/StakingHandler.sol | 36 +- .../dao/staking/packages/StakingInternals.sol | 15 +- .../dao/staking/vault/interfaces/IVault.sol | 5 +- .../staking/vault/packages/VaultPackage.sol | 22 +- contracts/dao/tokens/IVMainToken.sol | 2 + contracts/dao/tokens/VMainToken.sol | 13 +- contracts/dao/treasury/MultiSigWallet.sol | 126 +- .../treasury/interfaces/IMultiSigWallet.sol | 8 +- coralX-config.js | 2 +- .../prod/1_deploy_init_staking_proxy.js | 2 +- .../migrations/prod/2_add_vault_operator.js | 43 + .../migrations/prod/5_setup_council_stakes.js | 1 + .../migrations/prod/6_setup_vault_tokens.js | 1 + scripts/migrations/prod/7_setup_multisig.js | 50 +- .../setup/2_deploy_init_vault_proxy.js | 11 +- .../test/2_deploy_init_staking_proxy.js | 2 - .../migrations/test/3_add_vault_operator.js | 43 + .../migrations/test/6_setup_vault_tokens.js | 1 + scripts/migrations/test/7_setup_multisig.js | 38 +- scripts/tests/dao/demo/staking.demo.test.js | 17 +- scripts/tests/dao/full-flow-demo.test.js | 80 +- .../dao/governance/multisig-treasury.test.js | 60 +- .../dao/governance/proposal-flow.test.js | 17 +- .../token-creation-though-gov.test.js | 6 +- scripts/tests/dao/staking/staking.test.js | 78 +- 37 files changed, 1558 insertions(+), 221 deletions(-) create mode 100644 audit-report/Fathom DAO.pdf create mode 100644 audit-report/Fathom_DAO.md create mode 100644 scripts/migrations/prod/2_add_vault_operator.js create mode 100644 scripts/migrations/test/3_add_vault_operator.js diff --git a/audit-report/Fathom DAO.pdf b/audit-report/Fathom DAO.pdf new file mode 100644 index 0000000000000000000000000000000000000000..0362f66bc04a16c06482898e1ef8ef2bd749eb85 GIT binary patch literal 1265693 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

n07n9ou)NnW-V!X55@f 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

qmhbebrpo=` zbQ^i$`0*2>-sm!{qm`$-0622O5|*8t#{yTr3v`BEU)(G2UW^tL=TlV5r&N1XK&JXPLEHU>MIO?whEK zfY;!XMbT*DG!Lgv92DUknUaKQsn-#8K???P$qNQi6EijAs8H?1y(G&C?@*IYc_>>u zKenq4-KwaHvf>qebQ|vQQ~dkdox(=coUidO?yGc-Z&$QOoIjTZu9}3>QNKxr&%)nj z>^KBl2C40vV{7&ipnYp|K`N=5^bT;Z)(NiYHy{A0D%UAc^+>~jsL9%O(y};=Bydm| z!v3JZx1LhqV%hq6Oi|fXP(8T&HZwO=o-TbIS&#>~1mHDFTt2wEU?1&s^kFVdu-Noi zW>!kFM}i(`&cmJF0NwAJ>l&&F;bO#mI^i6P_$ z?~}E8%3uYOJeaZcSfeBa=x)KicLc>LqHBnTeY8AZCE3Yw6~q{$oWtNfoISpLjSrlQ zR*qQgrZl4&x?#2}Kc14^eD9^_*3a1s@%Jm%OZ7@y$%6(%TUxfgf-^+GRZUuvxMR6F zpLlo{hCO!M9$AuaA0T7T$M>-cE}1Hf3*L$@BTT}OYwviW`p%(pK2EzLUlx5LQzdc5 zwvAUAb755&u?8CQJR^Q)g1s(c4>?pSkVlT3R!@ckE%;DO^o6$@+wJ{T6jCC-j zOCrt-Top2!L02lwaWtiE>)i`a6i{##1vR!74@eb~;m+6$HX6irPjBkGJ^fcXs%GHP z$>+u3hL!klQDJDLSyRMuxxRhXOe}KUZ*p2J)E=U_xDcBg%@$ficS_OHIJJl?u|acO zmN30LJ!cFO1k8{Pw#D-YPq6JepXK^ycm;Fr&$=y+7i9$Unomjr(gG3mCXs!Bx~xm3 z+B|Tqc$I|EO)M45roJ(bQSNk><2RZ4^+QJA%s8f03QDQAP2O)R<`hHi;#e}-z$_fj zO`28}Z>EqN+=LBY2U+8%yUcOqd`KKUv-^1(=@{Gpm`3Rjtpzs;v-Lcg`ToHcu92e+ zwg=rmNd|_bX5QKCQj}ZwIPx4hGp>8UB!_5uZkL&*3a$fr$}XK4LCcAe;d3=yDus+;>K{>#K;+#Q~^#Mio(o&+~Lgj%6pq z-;Y4|Po}*E&X~9y;?ZBBylNuUBF%QJl}on6fmFGy=3Y7GjP$6h$(o_`+)nSoZ3~nVyHbYe}c};Ev|7s{vMA73*l;f`z1ls zentAzoNM3KuXlv^3^?8r7Rd9_EcS2n$D%wGl(m84!6y|NIegws525yYB_1N#Gde@5 zPKSvYzN8|vrQnG|d>9^a;Y9FW?5xl5CQzQ8QJZN+9YM~KpH4*6<|^}t4dnYR6=k8f z&6iT93)A~RRLgCG-M!^VR?2sAyrpd$-19l;OLz-e9h1GUhL21qt8*j9$~d?m=kMo) zR-WdP(a)R;h>eFmsJ8Q@R<7snU9Zo!u6ebx;k-m3qdErc&$cAr?s=11=7|OF`e8( zO;_mPD@IJl_ zI)+OT^FdlHxR|TJ?P7sT`?$TqXYeVUQ+yC|`16A2j;_=Bm!&CBNDiA%H5U#3_b8N25F69p2RpAycL zxVX)Ey4qKnKJjsah`On9Vb|gag*{AJJX_&mK+$BT4}4ftONMtjnBTT9Z0s~my{e!a z)-$9FKbXK)Eq&TRMEg>J{)<7R!+*UaDLPQE>U(1MH_S9ha7;Z9!2{$TfbPnbKC zh51Kb7nn8=q*8xR-~IP^U1o;=QU=8gR2==nS@Bf#J{r(;POIZ{! zm=V~nj}@5F$i@kb00uHdEX+XLKNB#%8`w;PnFtu3_qWmiRN6?^(9%xD-rCgex0Kr- z=(ax@TKgllo1K*vXw6~<#w9QV?N&hA9+)5iY^4TFg9LV;1I8u%I{KfAn~J5asg1p{ zwXnUNi<3Q2Q}$~k61IO#{Qae(|3uL-0)wZ4;oR)NK-%A+$He@jfeWx0+5gJuF|z!T z9slEL)4!avzl9HYsKCL=&d31F3H>d6z+;(TM*nKX_s`(_?NQdh(&aG&gC%}X`)V)# zs>|CWWEhn`hrj|giT#MW`}Q3CyJ!GU1UK^|Q_H{t?AEPwSl&RM*78(De=x5_!^0<& zuVJpFq|VcK-iBxTwGSQ-*JqD{WqYhIiQ3)KPPp(zvr@_a{diaBfaUe#ZhOoV3)9w7 zFycliN{)7ir_;OrxtlONbWs z1e1K5?r68X`t8kEl$EkW}Vo|4rlPompiwwq(p*s~3)I4Akiq)zq~#85%9csRc-% z%}v7=m#&6x@>%QfXiFzR7#Ury)FqWEX2mTJw;o2Tl)X8wDBg9rSgQ!vZomaxnsbcq>WouU*HnQ4f8 z@vxD&aoo%bw;|lSTbEhvEXg5IH(VLT#sr$LSMyRwNj&9aL!^z14!Q)h>0__uzT503 z@%$GyV@==tVPZ$>g1Qf)W%s`SnruuL9 z)oXFY)gKnL#wzoRKV(N4+qlKph2q+JAId4_iA61+kBxVKa{pCLl5NGr5;1*3OzWH$ zV<2>B_S}*N9|{K9;4|*CHobF1A&~y5?1Rpiv8gWUGz*pj@%iks4Kt9KTU-`mZ>rX(e7Aoo;g+lbK_DkZ~JdJLyvN%%O zznHaN0$#wYb9%`d)J#JZE9rT~N?|6S= zbl9@&z`dkC$$e})grc5hOHZuQ&1~exdl+{T$9;Q0ax1hreB!#mdEU<(JV}G3Z%$52B(01L!zIyk*kx7Em1!K98RPJ^!}jDpz-(a6>bq8Np^WxN2J~jb-Kg*@eSNtSRUf0FBGoEt>_2qd;+;Ayi#mhQ7Ew zC_lbG1@~SjjpK@kZ3VaJhnxFM1eDV!o(PX!Jq5Hltwi@#%HqV96ni;3tp`50p}-*r zpU>|wnj3k%Hx<%PT4Hz45;7eHX-lEhEp%1oqjjb=L;Vvo9ZSm9ZKI{%ZjQ6t-)g*N za<&Wbgjchm<)?^?E1HC%ou)q^wTtDfos~s|RME)oDMXiQT?{Jtek?v_UnSHzZt#(k zqFOqG9YgET?&BN$a)q@(;CE=}=1`P7sIH8{Y)h<`pp&V2b!%P|P?wwcY?t3r?kdNn zRSD_&A+gc<*;3;rxK^Uuspta6)=3Y23@H%PLvZ1rjY;UMSrVN$c=tMY28AbE;khE& zpoTyF+!H*c#tI`MK!B@@^p{LG^wVZawMeS1&YZg?QJ=dA6pVWS@TE-X!#ljuX>3el+lSx zfX&p>RVMeFbE`B&FXrNe=$|M=KHhDgo691!c>wx4=d|RAg#xr0DdT%$L&W5yk{Y** zn|5cj2v>N7H*qERt|%{teBAb5Z=j&m(m%4%-QCO_4hFF zNsZHMAodUMDBYIhFXM4&?qhM_L}E2J5H4&gaC<>!oQ|TT;R(+A+6umt*3q3NeI1N# z_GcJ~r2yOPh=j=Z6Iw`B9@56KIS7X_l@3xpY~RuK8ya-^yind7*j7aFxDqMej#*4H zV-!+UX@=jzE}H+93fTvuPIyVdSW{MT=)GP66K0@raJ*=JGFd-q#aTB`== zA&A-^>eTT)N*E(Lw#82^9IDnikg#Nl|x~4LZ+x4skNx&YDUEBp-icji0UO`dO#OwbF z#Rk-D{lBKz{>%6sX2xHol0ZV?XQ~ZIT>bL;gYN@MC>ejH;28f0oQS_%{7WB@<7XkZuumeLk8GnRsG6Ewafk~U3?0*~mkJ`Pv{NUJ}>DB(uxBX&4Wco)3 zBJHiWiAlJsu$o!*c_iq6Ma&5ni{zU=%t+4Ii5bLsY02}Wx0Q)ZzG5=`h#>B|X z1OyD&bDE6<*prdv$9(wP=wAUa_CHqGA9?S=CI;^*Om z>av+xSX0WdEjaTrhXG?w6)B(gw@=+tNg>g_yFxJaDEu?|W3ty+@CUO(YW$`S)lU~X zt<-#(9>n09=x{+fYpsBJ~9E4o|H ztu|mm>6FpoQs$06o|Ma~B_e@u{UQ|?3CoY^&d>jHIewWezrAklc*|a*;K%Eew(ohh zym(b&K%9}-DGqlH%i9nq$-v_9E)=O?3L?t{nFWM9k$lzn_TgF{v4T9*k(ce#_G`D+ z8nQQCXatcH-@sILz{?7SHj`&=WFl5W>g59;dG42TXvfm$E~JA)qLtFUchg3p&5SJ+ zwM=?ahi8$)#D1e7t2mg&)m@^I#|3BNkk_yibX*ed30C&ng#pM=w)=gFQ;KKG6)Dr4 z5``Er?O+0JTsSYrf>B_McsbPvh@aKE%Jf({0ktz-je>=|^*m^rt_GcY+QT!AwysEG z>NBYfIZxj?05oO1Td0EvjJ5AReBPhwH?qov9--nSY$~xUzQ|QxmTO5&!nPRc3kiDi zN!iH-5LY40CVy)S=jVxhgd6fO(TEWnM6!%48R&A5Qb#M@NxQ7nc0lIY3MDQI8!{eLRrv!b1U%Qy z(8cP;oYjUhW1YoC_=sS=y4h08 zMFHB%5n`IMF%p_eyPvY5hmA-8<+z5&BF)GU^b`kks4_`f=EzB^JIJ$Y?!fP}BPmZz z68)YMnGQ7^Z0T)*5eAQY-vPzAXJ2Q!X)Z)VrW@_L)G_^bC;Ra1O?9C^qOC4W1C|@z zN1~bI((rM(UYSlBG!hj!W=-#Hg^_h`!myJR!@~$|Q-k<}rm+##mgM>so;lb0c#3oU zgRiCa^p;Eg3BAUR{6&6Drq9zI2k|D8k2C<>!?rFzX{>VVG{uP&g!)gEfMF6WYgm>B zJ~k8M*gm*0kd_(-2xJZVCa7KlvVGn?WurZOU+bf{*)!08#2r+%Dj+nr|f z>wbqaKB&f_a)OOnA4fN%dK|qfpUEP4)6{#+X)M5hK_H7TOg`!eZX{F0ZmGd=tKJ4> zG67zX{!_=2J`{YQEcc{^gs?4kW0qHj7TlthRU#*o?3;cG+RHZ+C0iL}LB6dQLArw( zRQ;{4UKIGz1W8T&W#1o}UPmR=hI(mZ5e+F)?@YhWq0grP>heYo=j%S~Zn`19wQD_= z#BJ6q9+0ATMTbXz;|AM+Tfoc4__=sS;EJA|@Td1WVcQ;!C4a-#sCUv6>J?Uf=`cZ^XukgQsw@42Re_rkTyifi>Q)jnHee#btC zowa)B8iqIfX*unAbNJi?gS=)5neUT<r1Mpa2ii?>*k$x!FIcAFHjAs5~=tEV`0?XU1k2x#L(G*&<$vHY} zEwA;6ney8KdR#hmMGm3FpDFN%g`gE92>`s6}IU#17om}%4|1nfV|!D$oVNw zkwI5^zLX%9v~4K9-Rm*64CJ=x2cCw9k0gO6Nsv#U^rD9Y5j2$#bJ{G4XYGfQEzH5F z*`{oIllLUVshCXIx21iW5oTQZ%&Uzum_1NQNJ6bP?YF-Sr>DRebXvGOub7A>vMx5A zD3Gg1tMX-NgD#AY3q0VQ^bk2}ltemu7xaIrO~-#Jp3!jj>Xiyc3m`r+f80wu^L9zr*_81(WDY0n(_038^@WpZK*SyEG+@FG zQ%N3Ukfw^QlYOywdm4~)IXkVa{!R9CF*f?_k!tYHLVy?7aS-V=;FBD#qP+SW@%qO! z;eNSkKq1uN=VC*aFS%L47##^-T*j^gpNpAeQWfP%s*{!FXHlpeG2mOalA~(V737(z zY-D*yNAJR>0kwOo(*PvWIes3qLoxjal!p>ss^DgQG5$J3?rCezXA@40SkCk@T!6e> zwSkRDu;wjnvSwna!*gGnzreihuV=kybG5Z7RYC1NxYO8bSPWhru_g!@|*@>RnECzU2qpr z0pF5RNqua#ldfi*cu(<300*Q7nAtdG*HQs%Ke++__`>?|OYNedol@j=4DQ$UzL@m-MLOVL^Ed;V z7*$ouj{;vvY~8tB#GY`tTr3)3_Z7^jg{tHlI(YTvLJ+v@WkcM+mx2&76%9xEJT1P^ z?o9yXG=xH;_G*#wy+|EQT=wv|-13C!MJ4(i;qo2f@wsa63SIWF%Y^&NGCqt%AmGQg zWgu)HRJH~%npKW~ey=i`@`c5aHr?4`VW3uvUO zsH5!xAG$mVTH*<36GgErExFjfR|g^Q7mUj46*8^`_zkW9A!j79mQB;da(R03|9 zfmFy3Kc}<3tCO**Gttl72n_wt8zX0+#gm!wR|6{0VD~d?0_<1u%j^Gu0ri)Q{fW=d z?5sfZA8;cJlq9io(s8h{urvLz1Txe8U;}{3zHBV4e;fUe+M@j*EP?;H-T3*Q{9nQa z40{Fw#SH9w`dhewjgEgA{Y%32Ck>~JEI+#2Fan*-zb!8&7EU@~m^KH{^!yhnuYa!R z`a_}pN#E)3ko$Y3{SLYR_)7aXk^3!6_pfwFtPG6*phMDK9>W!nYMWEu1D`5+B_v{C z2*fsF_x_sRBLKnu9abB4JQBqw4&>(gwyL?sqjW}T_$GO+CRc-Nlnz7F1YNWD=kj#*^$fH2>ZW`DR3CeD2={P9-M+obj_Km@8P~e)b2LHUl8?oigihbd`;r-#)A8E?ZcZcJ`otcN}6=~3fQYK&5zN{$Fp8J80B8cV(!0lY-b3unCllG*?zfx0t~_c zECNcv^g;S5Q{Zi!wJbqtolwp%CkP=49_P~4rYUT7jU8_Z-g&o zx$uKE?#|w|Kc05@J|FAP+>LPSbhCWull|~kEkcJC7Q^hdZTw^KYi?+_TZaSLrnbN% zvTevyK`u8936?S}yOHp%K}zTM?am2bIEDcDBSUQ1iYTr?lRdDST;?U)=#-K~rT*^| zl5lJ;=7%ar5N-@PiS^9JF>sj%Y%akq13fZ{HD#+a6D8PA@Y&?apg}(HNp#N*D~VVL zG`ea90haYXDYVNzDHV86GWU>v#k~i;4}cA5r|16d`0O*N`gn8RH^*YP1GoYdt39@P z-MhJmU z_s9S1niv%g&Ci@3tWQVi!MR?{Vs7dM2KFbA-Q`v;itdjF}?L&9L3G>b38ze%*Yzqx^>aqJhL9!^+T*WclGWsP& z&D`6VPk^vmPyWHsOC^-4YK+wT8anzmW=~DQATjPs4~DGaE}A0NU86B~FA8h*SXSz; zA$(d*GTIly-sjEScm1|3(4(zPA&A3m(_(W0wYMjse6*A%E&ROXkQXbQLRH~3fje{H zuNqMb{6+rJ7OrgY5`#J)CXI?N&MeA7$PD=4tDH=Z=tTP}zqM(+LLjCnaJhb1UCnbX zY|Fq(F8t=1ENh*9mb3{yhG$ym23z{9e8n`7&#@rp6Z?dL_$igE&dFrjaWSlnXAW6? zKa|AMN`3W^hr4#Vvc1%YeT{mS!^Prohd%ABnwBR^Hf=vSJ?QrPRlW^IGm;1jn{T;Q zeA$d9f0`c*NSysSTAb2tC!qq9Z{PeCWGgPQvr7K<%h&xH9-D`W!L3V-{?F8|yBs+t z4-qx{h#tvVoTWuK*UR0;b|w10y4Vgu-bGdwS36&iU*A$P&^DIH^(Lm>=oZlD3xQ-*(lh*oBU1u(}zkyFChHzy;ZA{E>#8l(%Bt~oDxD;8; z9=WD_N)X@r%f>Uo&M^|HclX`(R$yxB>IOlmQE~8xG+Z>0OCfKdE?==Aa4~(BZ5>3@ zr#qFztoviyWAUD8jQBbA*-z{%8(+8zPw*grg$YD`KQ-UV3dln~hHD?F>#Mraym^=H z9I5T@9ed?bl^U|LB*V8tLp!5Ty&gzmc>(_`nP5RmwC)@9=(fb^ZB&iEin_+(C`|{VJ#kPM-8HGmsz{{wz35~$Xpm| z+5(iN%>XjKd`_Ru0_Hm3i0=EpN`VGxSdiq8JVMwyZ$>@LS=%D(u@I$Lm}QpWjB>++ z6hxu}mXENRPv_vgUux@36gHgvRdvz`jJ&g_g4S|b8pf0*za+8EV6(qX1GDdA#K-1L zUE1grDeSAZwpZX75DG7eIy+cjWEEXpAmfp z;v;;%%>ZkkjtxUc^iFv3b;~Bd)aBCWM?qc24SnbPj5aAOj*VvGI=PlQYDFAxu3#J| z;sC1JM2DqXz>s0-LS~?L@-+iLp^I1P;EdsII{@fE-^fo66Gd+*Q3RB~wQeF5eIR2`v8Q zTZeJkE!)P)PrRd^-uZ*le6P`@$?T9~qh#mb&1YR5GVvg&=Y;XFcT$u-CVv}X#6@2s zwT#$c5TVoy)m~aGnBEI-6TOszB_VIskg?|*L+EMD&JpTNHHM~Uy_HwwBPB_R9)v2A z6rX3bDAE0>nsE4&dsAp?sfGG@L$RsLBshQPM2y}OV?Dfg>1Ak2H(VT3QhlxUf>HCR z4S&R9T}O0kykf-i0_$ag;~h>oyAM3$Ar{UJk~4e{Gk)tt8V+G2ybYwZ7o2ruw&d7g z3MHMhO-l9hhEo1a$=mccQGgWp+&yh$gA(LXhA!+gmtCE&VeSzdSj{3* zd7sn~7Rxl9r?QeO!_u}H;W5?1%w^PKj1n@^qlqw$f9;}2AQT<>eB6R7E_)@+sOUzu zP>}2G4Mk9{Ai?}maF7}F?T)kXZa3Cg#cr}NM17=xE9ST`H!d#Zx`|U4e10V4Nb^s>WAT!lQtiTVIZgBhRpb1v4U+%{Vuvk4rogMG?w|S06 zq({)$&p( z;Q_i16Y&D`P8c+&QY11Tog-^s8Cd@vx<_nS9{fqUq7{25xt&7Cl$2)q##!QC>~f15 zrnHA(*DP?N9sF&gHKHYV+ihZq3w@r>+?3`r2+<7ueY!hk4Y}LA#TP4Y(H%?=Ro;?G5*Smf z5fux44v?`6579_$PM>)nr_4Ae$GW!MlbYWQdK;Y?wrvRf2_yW44FXujV&EE@kP+tS zRtf@a3@$!1-QND#HAq`R0z)<9Nx!b@=W9Y~*p6@!qi4ICwJIG1#yID3q)J~`F#&fi zINtI2aJ8MCl!e$9t_%a^y)etcWaz<}htO9^&KZzU(b?un8_?~7tUieNkWVZPQ>#<~a?Bix+x;OiZY-|I&2o=bX z;4I;!+h;cz&IKfGXe1kbm~!4t=?C@t#sdG$1=-%^JVW3E9I8K#cite}ReE9JoN0T( zVS|Fz6_)indIEM>m_x|%j!CH;J_@N;nYtfjbg5od7kp;$z5CA(asAacuunffosP@m zl}toVC+(Kkl-)uIdJs)u5!)&_1*-M;8CSH7{pN1_syxOy-AOie>32}R@v2F;u4pwa zkuT|KGA-IS4CAy8p zs4s0(hPzk?FF9@*)~%0BrY8a)qZFrCC?ni$V3*1lnfQUJ3#uBTO$ZLj=_w^)Zr467 z0BKBp^^!_H1vK4nLt)!4s{q+7={H)G_A%wNwO0D&k8(B|47rx1RL3;FeT$O~>6W94 zj%x-~!tN)T2=yNs4#S$8=Z^Q+-Nx@MI#QL5J&8xdukzW!WelJj`nkN6W8Ow-^W5c4 zFPB0jw1zs~6oH)XjN;9pHu@jQ(jd0PCsTD*_imf`6{8{0@JdrOuBzFNvvkD}U2-V4@`#?VH%&u1nA#zrWgg{a zxP1+QaXTFdZ0sq>H;lDnJ2t%NYBZ)@;#QGQsx3}i^afNg%*0)*z*F{J$YAXp%V?aj z1%n6Dkp%defTYW1F3eL)@4r+Z@tReIG%p zOgn9%km!@X={=zq!?>DK#*;-?^Zi}f`7Jmmxk#WzrQsmZmKJjRxF+68RZ>A$P;>eTV9->*2$@-8qPN)SM2Ch8$HW_tOE(0*svqsLYCekA6ya#y~>fFWj4@HaNvR^EO z!(4^J2iq3rs@{1H70Ghod#A`l$=8N{p`W-&Xn9kQ~-fCW~SoX0WwJY=53~ zWPU_&%)_USFd0)FBUS$D^ciDkw@WCa`jQnBxQ$>o`$S71q-Yi5vWo#veZ1Y{A*)0EHC4+OeS;_eotqtyif({(>qHl)wgt6P@V9ZefwNAEi$Ql2fj@Ma5_V}>n zRKrpF`5+v_+2L7<5DyayCn8jv-u&V!9kyB{sZD|flLQ1-oh9*$g4{53P8}EGdEVuHLpX{e%x9@(9Jlb zX5$1gN6AI4nb@C`7`CTl7aPyGo6$-d|G7}2R{&2i^#KHw?kGMoex5CQ&yFf-?M256^29px?0JVh`02K$)zht&MWjOSCTJt2zL#1uYLESZ#-!h^gWz8rHL11 zDr`3-8ni(c;&dsT=N*KYyBxcpTKpehT3+vh33WX#Klb3Q486W~4!qVG(l;1&mbUUN z&xZ{PTlt~T46UHc1jVp>uo#Lo8b)JMiBdsu#^8v|7k4$M$}XS|$RW#+^5Cc1fu(^X zi!~2l(!M_XD;H^+{F74|ra#Kc{+p*Vz~hYn>Qn}J%<;=9%&+!wpp@^Ium30P<3C^Q zPaHD($1Xz zziu`8k8LKIfdKrY0{UNy4}XUt8yyD=8v{^%_&W@l{x_+p{l{@dPiCRV23 zYZm|REuTQ783jg)LJSbYl8*^j>wzMmY#G+itt8hYdt(lq?xJZEBhDNU$odS97!=Kj zlVX&4lxm=nGFv|RnV->X^5U-&@)6WZ32qi=;j{yF9vsrty8cBd*H`<;>!a)4iOgE5 z2H_zncs+QTcpUese9vAUZuSXTe$U5eCubyn{9_$var%6(&xe7mLz(pD%P0EAO1XPT zBPuqEj7cy&u7z-t?=6x#z*HIn)E&j5V`UHL+y1W!} zOb*IvdHjfaFyYzNjzb>Dj0bK^&G75}-8CJ{uP={_@`Od3_95o4Vvhj(endo_rikU} zOZ&pmFu`ORJT1cV;F-JBU;;1^uuhp9v*g7%*~z4M)-2)2G?Qz~~> z7@R&6A0oHyykQC7Iu~&GU*x@ISY2D1Eeyfk-GjTkL-61(!6mr61xavsx1d3Sy9WvG zzHxVVxjV_Ju2XgDJ6~7#y+2NOo`>+P$qsw%vEI2>=9uFh1DHHDj^pqbJU;?mBk%uu;;WUp8F z7+SanLy)qVPh*x$dt&Eq#0_p+R{aSe@KE5+AEh*fqjyBLz2ZpbAJP+UE?6& zZVe*?P5TllREN3c!8be^8ERU33fCmf*Oy2I9i)Cc6P2Rhp8s0RgWL~cO|~5*CLTC znMOi}uLBZ1LSXp&`qCG~%Acoeo`p)CqUPQwh!JRBnwHK@HPWj(Znd6z7N&q|YHlXf)*{mU8y3uV zbiM)!)HA0qenJPm@VfK6&M8)(_{X)gkoOS1Xf&Q~hq(5QEiq<3(k_uOr8)`aJB0L# zVUlyL1rwYILF+BrG)%6(FXu9MT40!%5)_HDLR#BNsrk&#pllvzgA0@YOn?;r%SMYb zVzb!VmoY{Vxc6eOBq(jsy+v~z>>YZ=4D&vv*Sq+Oqm-P3Yr#}rn8`i+Oc+G}AkRnk zqjpn^BIDNa2X#io(PyR`pIw9A&`GHUbU8eejGK8DACc;w?-3PyfI1kXJ9)PBrMsjBCVUv8*rSoz?r|jE`W_E*kefeooi(Ik@ciCSQx%l6!8J85)<_ zF4kQzHC7n+wsHaj2xyoo>3SupLdXtq`ryH3nM>_8rt`r{Ti#5*4x5j#!vWoiC}*YI z5CMc%ix-Ci!mpp5<1Ov{8zCth)Kx!63do(t_ z_lF%fJ0>8e8en$c>!&pXRpL5XS0NC2B@zHtW*9lzd1FpgZ5G}V*G4mLWV|r?F{=pD z5T`wk4lwC&rs*O4s}bgS2KSh z%E?Te`1w>p`{FZU{nUs+vA-HTQx8_9NqGGz!~3AKcASBGfUXB+h4Gh(gP3LA8Bt8j z2et`qmoOu(jjGC}&x;^PRO4y(1vei!t15ft-X5=`SuS-7%Qj7>DHd?9 zfwkhCTv9~50Y-h?99dS|UrS+t8-5r}-efF@W7NGs^lFg3N!_?`K-%i04t@oakFcA- zd=&-yfg4e(=TjBz2jtRFn~0#*Ca1iP4@w|RBcM#H5s{^p%1IA>pdHtCAa3qd1LgK~ zR83Au+~TD50DHs_peJkcxYVjv_s!M`jxzGBAm2cCDn;CxKm?j!6W*RCgFt)2HL9_l zpb*mRLp3dj$ssXGY{+U5_T4v`G$gei7=JTwCS(u=KFS9-4<33D72{e5P4jaTM;y2C z95}m2X=AjO_T7<&MxM3RsBe!4En*mG)v`z(D3r44_#!yYPr<+w#LQ#pHlW)LSJ&8& zKQf0o^|D;O5`#=JL0JeS?G6BF5X{!WAQjEhjNn!tXXH2f67VBlJ3Xq%j33T4ly?3! zIL%!A>B74T@R*t7uRS{9pmdZuDwR?rC)?6*9~U*jbQZN+i(SQP7C1{cv2eZ{RMK3p zzI0@Npwpy2cGK`Tx8rSd;TvDIFA@#O5t#TOwHy}Nb$d60W~H$<)5j3uvnx|WSLLu% zye6!zYUQ-;r5}&;-m&H6!bvsK<94_$7YRmd-(se-=MJU+2Z~P7L7)mD z<#sO0vs_#ic8dhR`IzE17uG!ij_Dj_o^T`j;g%OK$q0=+}-eHkRki~_)zOo%ITyHmnoviV>I5*~H5<9uP|3bi0 zXNE|&NzqY=nh9s8!?+~~#`2H^C<*8=_T*x+7Pl{$ZLrGb+{=W8-s&(;2XpN3)OsBe z-^KCN3cfuyF$*&^N=ZT&Oi_4h^6Fv$-1`X;EpEpYe#z%ml%cV^ZQl^9#~$r`XoZ^f z%fmXW!L0(Z*@f}V2c@FU#HTX;?0I@#k3om4mJGn6i_?2-C3#hAnd75U(kz+OL6w=S zheqOy3noU<8QobA&aA8x&Y?n=Vrb|SB2L#XJY%~} zLw0CH>3T2VtTyO-6eB7jSDjr}GM(xUFw)lBn$(nit z=LQn;lf93~0OgY>Z)eMOjtR0;;?K42z6d^D?lUqrg0wx1OwF=xL5$rmY^!~(GRWsq zgjJ_qJS4%ce@e|ui|7dS<)A>SaF-sBCXKB*G%FNf#B zdmVbrxLom>J-0`idWL;nci=Uj3M?qcVGfk$42L6B$d^?Jp20PhAfGg79MfzuwHv^8eq=&H9_{7${i% zNp!LPOw7O*ZXmbHMhtZ5WB?{XvjL4J{{b~1fBkFpe=usl z@ALjMjWUpa=Ke=M3)q8;-}oyc$1bgY9fAq`msg@@1t=8EIq|U8!)v^=<5zc2>4tH` zhOVPdQDm0tUGJOZt2K=)<=%1ePe^=RQOEW5SL~bI>7EV1eMSAaDFcvd3x_m15Z=l% zI^Vw?EbQ*r~5#gzi4B$o$we*aP`LWZd&3wVYdCj zj>+TeMuhv^(NvIM?CXg>492VrMp)t6(PVuPxB;6v(QMJH?Uod$GT;QwU2Eek;`7_oYk-haN1LhQS zLhn_J z+xE2PY0z)VrjLs;iU&!rcE@5;g^?v5c2vrKJHTCqrdk{v3bgkB<##?B#t9er?}Gx-xb3teEo!eXc&`ze{}_!yMSZm8+| z3uf8aj`ZDX?zht_V`Cii6ouv{vK56NX>Df1Mf-)F9G^|B*gD>LfAEPy3Hd0`m#T{P zu{l5p!$9bavgO!r1ar{W=8UlSpb>$no1S8%@VNKlR;n^~pccW=CX{&waZ_mdtHlUK zI3f?Pg-gH6&?4rJR|%pgi!=K-++1K#E>6(<#fXxOP(_2*7H3uU3q{RDFV4tPQXEVd zCVe&sbWtWudBTv6oq$gWijiEXzFZ$3`bl>h#MhZ>KatMLu+7vJ27DWT_qCV!kpHql zm}{sZzW?G!V_S6nR6VKBKd=jTiU2-RQ)_$h=}r+`|`^JkJNGz zdNppQ(;}2vms9!EGRj;-A{Gj9Leq@~Y{|R#F&LSw+-2}yAU4yEX`WWl-(B1cj89ew zbzh3ZOXCpDjNgUUC0o`=kvd}Bf;Gt|S{7}*APR2Z=@~Ax-NBKz4mEo3rNH}a-Q&v3 z+67cf`dg1GqrVEc?o`-!-(PLY&DQ0H5; zLL8k*kjR!vdxs{?<_wYac=l1S>CKADa`9^QgjD@5Z&_#C{V2_dpFhIE$IATIpAmH; z7}YJf)CoH3WgzIzYu_vvvy!%y9p@K08r4+2YqJUU2wQZhH^dQfG+JWV$O;YTq7ath zoZW1Wqt7$OwAa2z2g6V2aT^73eOVEeY~1iI1~2`(Yfjb z2J6Co_msnvMDe}FyA}3WCw^J=akH+0)KeCWBvJSAcMw37IjkVeY9vP6lZ;y`Yloe|sAx5Q z$WMUNu##rCe`RG9r^ZllKGr$elE##itIE$+3rrSF{kckGc?>N2@za=PlF zTQ2BPZH=)|Kk6ZG9C(E#%kSufud|s&;*kNIuGZkFm)Qq&G6hx&%z4!wqYL&-3_wiaJc zR36}ki+E$w>A~5DAUL9|Esx3@|7PWtEwB#H%&(OUC#Ra)C}*iWQ_H)gQo;L*UXU|U z(7rAQ7VTWOGol^vo3;^NyS*{T!!l3OL|J+3Y2BOHTGQl9+0uzwS(PNSRoAlEG~7cC zGv6b)%-6Z@-^Kp|y;YtQjN7zBq=_4wx?wD8$*-v&1p6$db6(L+$srjM!R_D`>+2v8 z>)YbI3BcbO&MCeks}z;G2H1UXN6a#1B&4!4fkiV|hkJ_~1gx2`+CGd_lBrY54 zsm`iUHs2Gya9I1$nhm3D-+jwG-Q{fm=##BfeH{YwZ6{=MTqDJTHPaXEyYh!&t@`aX zWn&9=yC;2%nCe-i9;LyfVjsJ$(f+aZwsTO`-iIY!1REXHoIPVO3YAH7)g%X%PAA;y z&-!GKFo?aq&aUE?J@MGWuq~bT@le44aq9>nOWa^fqE_}m+{RH?h>@l<6u-7FvT)ps zq<5XPD#AYbeMe_*Q!&BD%M2$o%vMYEiJt`fuY0*jwAwN|5pNqw0N)1f{)2$%;!XQkv0xxMLGtW zDzFAx>p8>$H2isVqdV-yjiWdgXj;iN=|$E%g`>jJkeNP(q&+DP3O5YyDUWNc1Bz<| zDHqMluox>DF!kut0~-1Dw$d6JG-=Q86yfg62Z&YVbAmV(JCmLqRXC-j=4=_G_v6OA z6(tT&YC1O?q>4L|#g;^_{*v<18KiCHELjO36t~hbeAatl8c6Q*p&N?*p1=>AJyc*k zW>#bJaN^tS+l-r`sb}zDTvw5BCi35y&YshIcue`sYD#q?@Sx;8)H0vQV1M<*cPVNz1KnVY4n~gafVWQ4)YS^}Y$_4u@JcB93f7JJ7>NabnOBbvT15$1ZDce{ z^f*d!tTPx%#U~p3u&omxZ1i5;y6uyYqE(ppv-kcWCy)9{EUALHXXzM41Sdx8lHqK7dk0qtdS?9;Q@4csv)vyUA~5*g=Q4GrX7Y68Bd4I&qjb zhlB4vcSl`pm?z7{khiKt@~!do#`o^*X=Pcqi)42@fkD2f+w$~9Tf-AmM2-$c(on(Y zH7FT+OpB|%iytTW5`X=(~)+3oUYV<_Y!~-#jjUbY65OLFi1|^+j6D zfbmsZBtIe+r;O7bb1@TfT{ymc@a4cZq5fB-+#mHt|4kJd>raW6u>JB10Irx-9L%jnY~6rH0zZb>*_arZe*Pim1op1~SW#PB=b3j_pyeAXW; zde)zB_HV51|LzU&`)q1pGy;%_V+C>}?7%P%U~({UvH$Z#l!^KHU>VhknSLyA8HIly z{YJYOIhotq05hAkZdgORN@qm+%4Exprw6MAt2 zr}w~P)1TkyjSXz+9jy%jDP=kz~9CAH$vpSiIts+gCpZ_#E686lN0bz^5^I; zdW4zvpZmCfUa0>XhQAA{{ym0&&7kW47KXo9|NMKz9MI$wXiV`l!I}ja3d6y{0yKipA~30JD#+=xW5AS|Gco00r=rxJgDpve3E@FKSe7kaD8{+g(PTofAvf`J;uo`uHJnx;xptlSe*DmdNK-z5CL9c1q9$lWD zAvHU7Ls2{X*xdZ&+~Udq=#|8uoc_ixjwmAqa&&ROP)I8}1~RW)JoW4EA!M1z2ompX{{%I#7(fM#WUj0*uomy`+Q%#EoJZ;J=(EvX(lsuIMeX`cz)DIba zu_wMBSNkWf)@0PH)~23#E-je4(nOC%t*7HOC*lVfO+?{Uq@VPXcb%PvH^b7>!JDcm zC`6O6`aUezc%Xf}2|U}fh`?Bo+Igys%$(nZB}jOE?_|4)rLP*a5ezEl+Xlb$$S&zL zh-WDt7HAkgGnw4>w8L1j{J7MMzV>bTVouti;8+HQCN@`G&uYIj)$mpV+~n<7yj0R9 z+~YGCcDq=IucJq2&mA6>+duWCunraOaTlpn8rk-16qn~H0^|MB$$ z6b-SWPl?D_OzILwJjhi95StO%@5`cs_#33r^%-k74(PpWSPc(KlvE7rJN*rrXGPBi}=+Ucd&W~F%DsR6oWF2kV{a( zLvbEjS$rjvh#E?X0XCsqK!;athF}H)ZXV;qtWZg3w3};q1-Lv79^ZR^n@8%oZK3f} zbWqA0NR7%_1k6(Cve<la!kWIf$*40DsTzW~@&(4H- zh1YPgfe<5r7$0lV^oUo6>L?WS1ssS5gxl_5=GH4kWrY~jboj&__$$^Q%D@j}7_&@q z)AoDfa3v-D5ch@PFr-Q#bLnMm11vWRmvqI#n^RUp@ zZ|B|t5*p|8hZZ<=85UouF6T$cqpy)CV$H)?h9V5PkhbDtQg^02fv+h;SLj z-|#Dp%jUGg(Oe7Ff-6tQ+Kh*#coLRG4tyBcB~ajQ?fhhJjBNCD@L}L^??VYfsHDyW zyT9*tCc6U-6iuG1(9v!+FcbG;%HCH!+a-3p8T{5Gf;!EE@UsONDfHHY74g+(DTykP zCT312x<@0?3FjD~(+CehjbY>;%T`cdOucAZWZ*f#0WDAH+_3GvrJXqnYXw7^0iJa5 zIexCxBvX%(aiCPpmB3t2Q-W!mYNv2$TIvGGVP**IfVk3k?C8sT-6&TKcYjNwo%5;6 zl>x^Y@6F$VDDn{5t8veuN&NO+Unqo&U>?UY@O_dKx%CExK{tu2x~{R0c+fo+!m;su z`0>Zulo9q`g+})mT<4Yf$=xW?$gzgcJMX_NRrf|(G#-lEUh`dF&U=(sy6-o%TfW{U ztL30RvIJA6o|>PrAk?>Cp$v4caT$e|>*T=6hEY8NsW050mr?|{Reb8G%GAU}J($;@ zPn;Eku=Rl5^w`CF`zd~KauxAjBaB#(VGoi&t8u6EqzL{#eI#dP+>F>E0->hG7yo{V z5YfAgk7h46vTLHjEP`O#VLsyLD}cGt+r=BtnU=&!Q`sl!LWf3n6(79cWfgOOeiujR z+UMoWaUBPN`{h$M=hv5Supy=oRW=1JrphD6K3fyKET`of7uVBv7lnqhvqrQN98FOW z8@rLQ-}a(Jm&yH~&jh=h4>rRP=NE;a$NbqLn8%f|BE`Gu2oNp_=}YS9k0MPFH)Ir_ zd`wmvs3Z+Y9CCx26ITv#TDQFJeAdH;GMcvxr=w3nzdGerLbKw57OULLBAcd0u<#62 ziwX6Rztgl>BE;E<#-(MH7R)p9_!1wXXfhvOE_MpM42JpY4S%~1(bf}5-IiO4i-PvO6Q@9x&Rb&H%sj884NGt?BGC#-(M1XzfzhHi%k97^>WF*COpxO* zgJ}%uR}hKDAGg>)9N!now>TWnjzw^F@w{q<(kwL&13M1+#ODb{*jSd1E+VH!{~D1( zpq$?uo(NNZ<@zYa(fe!k$)0&YlRyABDFeZw1R{wqAH$0ToO=}Lgm~rv=4|+Z$$fRR zVT^UPANp=eUwn!XRcCu`YG_<3AC4!LgX>_*w>9IkL4r^4_<@a|@%ZmND2^xfnJ;P- z-C5F~x#lEAQpgF?BY3Anz-T_`y4`>klA>0+*pHjdhev|I17WvN|Bvd|Xv{|?NOV#; z?B%ySEJ_`;xilR$lCYg|j2Kq#dwLfqNon2|Hk~N>5XSNd{pE`>=!ZADj9`0BQrnj_ zgM|S-4}C(~kot@##vs?2iQ7I|rnz|51+1{#0BuCz=E#iJJuTow0r$hqO zJFeE94dnuY+oB*TL#aG>{!wK0#i;^92-<*H>Wc>x1#w$4e?uWNw1 zQmz9(qpRgpmgI4~LSf91maXB`5TG$5*pZ7O%Xh_`iu4o%rSK9lz>psMNJkj+IKp+R zE3Z%!wns^b-I#Dk)W{N#2myK_{SmR3FH4Qb(81FSc~Tq|QmXIV+dV zmL+teF_PJtmvZ`5VF91Dmq_@HLGj~}-g4{H;(;bNI-o845iR_ZH0p6O+^F*#LKxHKN{sY8H^cAD%J4b zB0y-vd?rxJN+Q}3naL3+fit%p@uS-iz^W>R2`FVnS&sbljBJc0=-mL)yo+qgTf(>L zX?n;IuZPhr2bGPWJ{kh}IKf)U+x`rP{*4FjUyvZcMZrHeS^YOj5VoJPqdz4bW%3vAMWfNzyJUypy3!$ zne;>U@N4uhxrnkdH*_#?a0fbAx*9kbJHGvO_-hr)#q!Vm$Iol@Uxg3Yz6e}^0+*ow z03R?a_t)tE2Kat26!}k3AFMzz96J*$FqH$SsR8P@Sb){XP0R+YN#GYdD+e(%un>P6 z{Y%1UXJBLrR3rTd2?wMAO&n|ttbU_GxY_?ufPbWE|GfR~_Xq+hBVhRfTYdilL0}Z~ zuhIV{2>!ka^v}2uR!+8`T&|;&gNcDPtXn!jTQds39>ph1k9ibyYF)7h3>h;RMKt6* zS_5;HSe($MFIKNt+!(5VWmMhDrMiEQTTS50=AQ-W9pO1X+>~GGO zg+ZBH*MpXXX1cX#w!7rA-w?s_JUT=3Sv%`+`}yST%S_n}{(_$;(~U2HS1 z_}oy|Tpo8HKdARMIGGW&H+dQWj5nXxMzmIrTRU5oN5OWFNOxI}^E^fz?)DiJ8`+(( zsy(E$IrfjZYK}YJ)gD`~;JL3HJlNe-JT-GRSFB(lgvQcMq2KszcZRj>QfmrovIHu+ zdRoqqJT`dV-8{TJ?mRIHo*=a!>pm}fEWCK!-VLM;&Uq{QhNisrla(_R-RNN|O)SAd zg`AM%#)B%K@1gdDTcjqv1E^Q%y&S#6lS(@s{L(V)lAD#w%-qu&r95+`zL zbNxFMnxPe{;B`c`>2Y#ZFt=`cYGX>UvIDZ$>+=~29k*M^UJDh(8j2Ug>2Z&=%?L^O z{LThLc)zgR<>w2ciuOAX)%cHKi|gN(li|5p%i|vNab!Se>kQ#CQka7|CYLtUPuV6h z=xBI!3i&2er0ZK4ojBA81xrsfM`|;mdUk}b{0<&ECLZqU$NCvnORve*ao&0-e(~xu zbeAYsR`6hQ#LL&qjU!Ss(h3;OPo6C8_27i)u0!ky$H@T)|d zjH6Hkc82aU*c#>s!X!QZ3-mF?9SI|%+z2V6l6on!;OWJ85s;-V8Kw*59`TYao`s&t zq;YUwJ;FTIjk^Io>qymRPBVnv`#sn;X|2^Ty~l>B{<72%5k#(tinAY4T)%TzY$EW8 zng2LvLR4|`LPIu!%<(dR%Sg${gdgV&MK2c+72Aps^%Yh>A_FqcqP|l$-UzC~f!0)3 zEX_k8olL(>CEziNE9D}o@(kL=QJ@wy`;56z7Oh_9)$sIGF@<8t=NyWn8%HJTkTdW6 zFH$s<7}aW5&`zs{ktEhywPB7rJ4}5pAzM8IPxvo`wcp&DwOUdpl)@vh9NR=2CR#1( zOVru=KDPj9iL`syQuEbbzQ80~oONc=hH)p?pldK3waOIjJJ`kcKpXJP?<#swKSJ}# zp^K+mX%+JiaPx>AiFnSLFz%UHzVU- z4FI(S^?*}~(aJvcJ@&qWVry?k#Byy5d3p!!>v$G_4XuHNFv4=aCfBP$Q^54(&Y?D0 zv<3gg`>yeHlk;W_(yr<)ilOulU$rXxqpIuCpKaMLo?z$gZI<=pR`UVC=kOi#-|C zXLH5GQH6Xn0C^fB(`bMc?7FE+FTK`GOEzehhs?@}K_-b{2ia=yupJpy`b!6SA{F$8 zv6uP^SH>5OVG-Av?(%d;%}|gjbbLC4>(bM_AuF(y)$134x3<+uY^+Tc|Fj>pU}zxE z$=O1Qk(AEaeL9kS35g0dB6m1>Di2C$<(2RT9`60{@_ZGNCUu-cxEULIyx5>~Qyc_p zYSo6iXl(StQsof#jeuFPmVf1IHEJ&D#xHi@Z{A4MkusPn73Z9V3{mf6E_BOn?5bXc z8%05-EWnj>Nw*bEmH5K)zjsIX0Y^+oK?#y&+fOhGinVE8lg%`Ws+gdSlvZB6*NqLd zkZRvhnA0BecyyFRWq}&3N=FsvU3!a(U#a%iFQ6r@{Q#c#rE1%2}Zm z{_YENiQ<;sr{}i9t$f5S>w9*zgp%VH!TUGLc7)F2CsBmTo=GAc#WxaJ%(y<^_)R}1 zXlWV;(fCd^T=yaBwTjxSWPZM%y~~R&ypYHmlg76X$)FLu>Dr=e=DgvZCo|4sz->E0w#7hc2^nXqshXHG z)GEaq>b4=CPE9{$p}?z>Qqx;2<$7zOADYJ^KHWa@Ie{-jDlROJom4IoIP-tjnVt0n zL7Q|17mcj-fhV*1^hC8R^J`G<&~ZS#p@2J~Lk|&;QR6U?G2)0bYA2MNH9_N5~ANP>Z;qfeaf zk^I0@UaH#td8KYd>1sDY^=(lPZ7S@o8%8)eE}aVS(@lQ ze_WE**|9t$1I9}lrwF>V^^(Y@f1jIsz{O3*kKmGMR^qfgP}s7>oo$<0`?6&jIV|J! zQd42>UQ;m)z&+Cp3@yj!Rk=&;t*vmrrD@#;ssqbT*x^bN<16^TOmoF_@Crm6w4Ye$ z04JRH=z=^zu0RrvnRP2nMo1;eQF?}by7TJ%Zf6msgUs9Tb)=bxTl==#4yEDbb0hi6 z;-&O3$!O?#u=v2>grpjr&`p&2hke+M99yS7gq0~gP5r?n=!|6xiHYt@v0PzOa7ZT- zNe#BDt6mQA2vR4U`9eJVx;n+as!YyY^Bge^s|FoN2a3cpmk7_H64-Js7T7xJviriZ zfJBM4zA6Z$8$7#tM7?4lq884J<$E;j8BV~@v|jY%Gu2HWb7Zb#USM)?2nKznLUl7H z@5@6IINMw;$tN{k7INaxrm1emSC!5iX`4v%;p8Htr`_W0XS4l0fh}s|rAZI9#A9NR zL>X4B+dmkeZwEAKOR9gZMcXZ18e$P(rqM?0o5Vd`HI9~q;3qFDpN_vh#$4U{RHJNj zwMt)@;eq*ndMEq3l!In=OH(oJi}KjmwP@&VSgH!U_O&8niARLR$!1$&lC^*?YsMl^Zv4j7hzL;EtHGxksJ<-R2Da!lZo$XIB(Fs5&am;Aa8jysDq`X_0L@< z?_NfG+Xw6?6=+g6Ivm~Ax(#B^L=${tEJ=;&yfrpI4>-;}JT-`>mZkY56TRhlLx!wL zjFR@U1KG`9>-QtPLAse!n>74oK(tDG%584&IXG<5QI?;9Ql z-E?^T1t`~TyH#63?vE6RSMR^#FM7Yg@XnW1(|K|;y;w{c2u$bN&3_-!m6M;%IE)Iw zn2u(*#qo?Ij_5Vf#-cwB9()Ff&{H;T{J0ys54v>{e80QpBf_3?6DroR8&-@Q8~ri6 zj?!~GGnCmh=6#I{g_Vvt8bTZnS5=Rf!Dx>PGUYQw_-k|#2Mw;RGE zuhN?89ky%rgEW2d_7ygGM76LF5=r?7duGmjti&Zj@N)qoLWP4Rqqb^I z@eV?_x^xdRBpH}TXl-gCo0nW1YZ2mTyqMn1Zh%z|<E2%K{)plbHmTotD6`^QZtiaP_joI9p5^Hc=zGp z6&j^((i2!)qp2z0-|p9YD%Ld2VqMgi6s{aw`>5%Q68OyXce1@=wFn3unE*cy)Xm`i zvda{9(fGXOUO-E^`y@PEp?H;-OFL-+U%M#tGN>_o=WG<&hn5<`95J-=e79Kd>z!9P z<;rMvSEM4KO;40&QwD9`x#~og?+4%&nNKjGaaUtP=~Bd?a3(4Y{g`M=KmtX>QMYv< z@uuJ_d2|N$TZ2)sN#SfwWCJHbFANKPG88HMcHI`Pk2-JQMUH4B_Rm!k%M731bI=iK z4eZmNd&FKaAH3Rju)hY=$`s6QZA_RSFw~J>szN7B;Xg93T)cX9Szm9p`KHeb0ROV8 zL094xw2*Q~v|rd#UxEmE;sq}kN#>UkchQlzzgi;P*8jP$h#|bBd14@BKlgJvazJZI z6D_@1G^v92NtD{gAP=k@hXNOF-vK|e{> zgVt)b_>kXSocK_*BDO-updOPU;@d0^Ly>kWP-e$7&*aKYP3+Cx8j@es}R;N$*<_jT7!=_Ays1a=eS&@dHUzQ@54ehi4`uX3D0xIHB=DrLLoT!9^ zqXwW%@CB@7)Z^t}QJH`A>G|(cnLou^e@frehcj(?*% z*?*%t*?&=;tiax>UqAnU;X=mtZ|ZJ1nSsP6J3BB@mkpQ=!^Q;chy#Y50EHxMEWp%L zE+C1*&cF!_+67Xhe{JUEH|kT=z{<$k$^h6O_lx~xVWxk}@&^Uj&rADnFrdFf@$Yys z0|DjcX60i4!72mQOB_H#>Mx4opYg~49|-dA$J&*+`Lj-PAF*5-rbim{p?!S8N{U(A{_{GQnxB>nFx*yN1|I&?* z85qdU#KghD3M{f9L{>^Ql-&Nh;>kAlT&j8&20qy`1b8#{-v9bVn z9sgQW_FqQX|DnwO%?+NvW5vzMz{&nT=#K{dTs((O= zlarYVs3rJIJu-hQsy|2S_ltx--5mt_6aRx!dRSY=7HDPAHd?Xk2r_AWhJgL5s=q75 zQSuR_MKU^ot?rtI!|>$Q-NRidfGmukA8B4!8&!P&PGk6W*cDmx@aMCKZ>#cT{6~U^ z0!KBWx*LUT2zt`2(54pogQM{QnF8%AtpIPn@!W*7c!K2B*Pr$8y3R*0?`8p$+Ig3k z2e!=*0GUT0EuZ0U?Nv{OoV+XpBbouiZX_LoQdg_k9uo{L1JgmmLYf`knbYvR)= z*Z@uPn-z9kq_2mee|FlB#+iY&kBv>- z<*_#>5s`;>qiyBGjM+Yg##iFwvVtI&cD;owmPj7c*}Ifu(FIuDozd{wP`aMz`qsjo zk+YCNUncghYk3DI4%)PIS<{|ew;Z0~sX{=@u+P~W7fn>gZ{io{2$_9dDmt(@_PrX$ z@NWtl2$5-Ynj}#LK{#PIX_rhEi`Q`0nJs9Kd?@XS^o^+R6z(y(=teMg94;G`2G5+G z1cwSYpjLN#%I)FMY^EYMK0wa9_C0tZk}jJva=S=b4>mXDMByCVS>`ZEzY!NUYa=|N&QACaik-_+Pj+Ki z`is#nW~$2Tj9{)zkJ~Z**c(&{RyD#WjJ1ZjgF+IMa7;(j3YM=m5r+Y#{*% zudMF{n($+mKkf1vy1h-`_ zNnjr+IMPX5NA2oD)q2VWu){wyQ!^go_Xrg^a1Xd!g4lrGK;|PWeOe8JSWnHIp7Uth zqoS~m9U-xpCJUt}3nVe4x-x#J5cyisv|0QbyCs6E101ohv=Y`MLR&Ti7sr%O9LTy( zVz~){CR-1*UDDe@Ph#jez_k}2=%a4=b)jh%zngw>YU=XoupjVQ~d*Fok}07c1o;}wD* zF9DdtM0Ryr4>WHjR~6dS_0mcgB|jQbxs*{dyfM1O8os9OzWz=kDb_e6y{|T=6fnc% zS{_$#l&81f;OtmW7^M=Emzy{4;V+t+&RSMR$z_aV69J{ev0oqvMpG)WKH&k`vRAb^ zccmLCuN9RZRYQ1^QRNfiIkP1V;6kMO-p0#NX4bKINZ!X#Z0)Xofa76Nrc((Ly3LFo zC4qtR8lLnWOD5{h(Bq5FV_Lf&6LySZZ>iUafbF8pyvVuttkc}~{7o4V2cB!Y)f2cM zTxu0U&vl&VC#_RuPtpTv6sh|2m{>DGe2m?6gM)Q$GNK$u)F2``@f>)qH4eo>xq$*w zbSq4)TQ|QA7UFzKavw?jl08@kZih1t<-bk1mU=kZY<4-X&&oe9_jr8=aK?cxoBcN9 zth)y?wGK8yW%l@>eY zXJFQ|;4kzCsyC!U+4T9`RSAg?Xa~5tK1E&tx?R#GFn6by006!Nw9>_^>Jvh_%4n$U zXGe2~kh}`Hrdy>qDmyVl+#!x~Y3Tjx4OfkdW)T|R;Y#^iUX5$Z#N1NjJyk2T_5$m4 z4XeAde9Nj&?ZX8^&KW-dE<|z?sMr#IxBttjzzNE0Q z0^e}j)d02iR?BBLXQ^R9beS=g-dE9BDw+&W?v}++q9%*xE-J==WGVRh-jvc@0=j&k z?M3-_<;$d(93)NeWmTd)EyNU`hSlzk&99lKv*uj~YmeNd@~;7KdX73#Q((B@elwkq z+57{+@Ex0Wh6L6&5Q%F=?1FDuUy}0|SSa9|=|2w<>@}#;0G$CHgkSh4?<#L;R+Vt00_*;9A);XCg399M%`4uj=Q z|6#MEd+kGVX*shUSDtvijnT#N>HIO&I;A~JuJrFJ}z8Tnq0dG`uc{;_b6~fEod~!aT7BJZfNH+82FlkS?Ar29iU>g_R9rAYlO30g5PI~ zq_(`mo1~jpq?Wqr*02)kk^Lw?dgvt4M~|Q+!2z8kByJpd2m}rtR=cbq%vRp>^1_IZ z+Xg+TAc8Gz(ZuCr$`@_5>=Mz{RZ&|~Hf`^1xcM$xEpkL)|FMOcdcm{V&sB%`4~1WiFd zH#YG2`lx@0$)FQVbxT~V_(Dx!k0ZX%3ja-$RcyKLsNL`W=gos4liDJOEpZ(*tL zO$^T$@Q0mJRD;ira}9Z=@-1XWVD0CDFYb3IJM`2(P9w)X;u=D=8A{X!U#Hm4ZU?m( zwYf65Po8q|!0XsA)P235_D>i$m$6XK&Sy~Du~e5$7kIRy(E><#)G(Fh?rWqV{rTCM zGr=28Sj^oXLfF}IYIfX(qWIc9O~D4@zOs|#@g<97slQc6OQq}z_gKF?mvr?OB9|~> ze9{73;V5F4m|P?tPe{8$Tzxv8fPfTn4cNl|xX|;64Y(>+!BdDQ%5J9JUQuxc%L);S zAf7uZY^E(xKPdkc`z9|1;BdByy>2E`RSQ$TcnW5YB4+5Fk38<;6OO|(isuMP9&Rh| zH5C?Dfi>~yu{Pa0WYO!%SzFgF!V|X2(pb`P^y+f<2A)~{>Y53eC`>y4&Ho|qtHYw~ zw!Q@fLyaEq(M3a73mNKL|PgFN$C=hl9W!R`EEkRc%F0g zoa?);=e+-jvnTGge|zn<*50dhBP$NNR+GjHa)sXb-(Xu4N3cW)eNvawmx~aV6HL>M z+|c?0YM&TQ+V9SLO^u()Rn!j0X+K%dH;M`14{>R$QL5Ozwk-19lC|Sze4*DeNw<(F5ocwTb~qAJ@d$? z1h{FA|DO1u*iL*zP7N zJW@2C;K|j~|d?e?0ns0>9t%2Qaa6(6fL*9AF?IA1F!7%E1KY z0Qe8MPh$tOu(AWUL>!D?M*lnbNn1kARiT!aP*Wpw1`FVY)5(h;t6`Wytby41Q?)KE zVHOUK47N5#rq)1d4I>*Ph^dhiM91``_9w?ruFWHf@Egp;%mjb|SH%jiE3j6c7#X9IniH4_*}83JJ90N4e@1YEB&u>oTBzk|j9 z=V~c`E0|b*=A}Qr#s|uK03~IQ+_^u%2aK|S{*S=-$5;EO_>74I1aKc4JD?<(SdJtV zJL^9bzJJ*;j)~((N79k~@*C3Zn^K=sVq*^;7akUh0JMVBQM>1P)=^nzV2zpi`py}^-}Jn3 z@wqw7M_v59Vn9!;3$2~)<+;utoY{=(HhcVoo5?TMo;FVhJWf*DRHC=lYJy&*?T(;6 zcmYnITOwwt)O0Piz9~5nGhcOaW5upleA`?|MQ2Fa zezZMKGDYco<&qXHp(iei!*eEVKss6-_KPK6jp5zR@ygxRIljbH`?lzVZB43(VdL>i zx1CtFh@_>Z5o5EhQiVl*MD@_uR1*;3CqCwE5xPEGLLJ7kW~YDT`RX&UMQW@ zEz%UKLElPYv76q-Hp|Unx10W;*L8*~8sE%$78ARUUfXCM)4Y)4AqvZ7p1DAcbDeml zwuX#>uMle2U;ik^56PMHMIC*N5ze!xuQ~ER;b#(wA`INQwv!E6 zSRcw#=6>m9ghP>4F>y9eKlc&l@?&D|)O%c8uO}ZQ+<3qx97V6%%C=v#-Os!jXA%w$ z4P3j1gcKp#zj+-GMJ^8;ni=lb_2KP}@Z1as$1Qcko&opi0-@__&7Z59(v?3dU#!VU3<8>Ah0&s%W$Ms*WmK(j>lPf>);-h@2u?&#TBJU(kGjH~ zYVV$t(171X3VL8yaqc}O58hIFPO6!EjK9xT72>UA_0%hSSTnSfmpH0E+DvP!-QTg z;KQ!+0k^%B5s&Kw5<;E`TL1eiwhyipcvL~wugwI86kWY_t`9MqFyeW4u3KPhEO+1t zJ$`c96A|^fcj=FGeMLG7t5o9DLfAi&-RkYGsL05(qw{xOjU=jz*ro~G%Ur>wYWG6S zZ0+z;ppTad*}Dy&(aymBcs`!acCoaqff~bUe+?s={ovK7vN;X^z1OonaV$tkuW#@A z=;x(6R?Qt~x^9U*NXY+ii@u!0?1g6wr|u;-nW={9zH2po=xDuif}O8pcv-71Hl8bx zzH4ZSYofyQfnG1oytO0oI_qt9A0Kp!U}|u#T=RZoJIQ2NBHT?P%y~bxC47+ed^_c! z{?R8o#e*}S-Mw4HO|SN${f-#o^w@ZI5^W&X+veGzk8TUJZk4=|KCsT6*-^!Sj`EB+ zhj~R~E6wKxkH-rK<~BbSG?=EUa(uE^y7lR)xLC|yiV$kr1C%T~6$*i8B2+6B{<$zZ z#I^?)t}7FuT?kUikQb@otr3ovxhdSv)`;&fH&rj!MQUEAV;q3}>gL_lH|c_-U`cX^ zSF{CmRySldEMIqY+~dwPoQvl-pbDw#C``*|{UDM`UOr0Mabw^LN3->uRa6{UOmbni zv?ZG{6F{A0(%L7;iLhD*U){cZ z(=XkKS0ht^vQeaqKiVpgRpy2<`-fiYG?6PW39w0rA6!XRb~oU{vk2=+H}luE$pHLs zQ+J+04{&3-9C2?wP7c%)d4Hp&J4n}8wV!RAwk@kh#i=n2RFJ(CB?uK?c%EEx2IT2@ znF`y}Yl2WRXCtj#G_jw-(*plaS5-+$_jK~4h!KLunzK><=8SV3EB#oG6uvXl{Tueq zA7rLV8nnBR?Vh#NZs^zUl0ED1noVRDSYjYGyK-%&6spCOcdjEZ6lKKVN>}sDbrB-w zYWbeRd@@1eF*?;CYBs?)ATrvOPxC28w~baWL7y6rtxm3`#53S-RYzYM>qsDrPHJJJ zMCB$tS2JKphK_-5%xqPgD3)e7@s@y9UR4;`-IGV5`I)JcHetE96^^=PAZ}-Ncaj@? ztTzXIg~r8(<#}XW&o+_4cTAMqK6ZHeGUi0@C-n6NZdNv)?d)`pAw#0RHojy)Se%|}k29NIeA$GAYQ>{ov`=7-cC7Q)^;~TZF z+X(rvv(`LK0QHsOx(-e$8(_JQp6yY~-W3#&jF8)ljPucTLNNpLJduBm{w41`Vk=!V zxfrSxx>;(vU4c=~50CI~2B-JgsJAzfrb{^BgYD~N^83a?>3L?cl&jOwx=%RFc;Ez ztf+yLI_a!@>H<-XnyQZfHPqlSnFrn;;=#P~#{GOET=m+otWkZu!OVxwAo?0wv1we| zqV?*uBn_S=4kRs?g5a?gejB!x*7lDkTu68KH*W@yU1|!wE{IR)xnhwc+x$jS*fHL7 z&9(9zYpJ!}?HZXE9qA?DcC)mas}YM=JnM^wvamudhUl(gSkR=5sn6NMnevi}501Pe zcO?#wD2NhNr^`dBkV=ciD!1IZ6I~L_r8Lbvi~Xry&UnT^x{U{eR6n`Rc;OP>&J8nj zA@_+eU7f0TJkBwcL1(>{{g?`^F)QJ2^@NLXr@v267Q9<{Q!+J{0aLnSYE~`8mueQ6 zDV4(EOsA!;)*00hBP~N}6SdRK3AwtP3-Jsb&3T4Xq6t;xcD7%96fUe)((18E!jQiM zPF}?&VyA(%&9Q!13nyse+}rW|Slfzp6=`JZ#vm4#>2QAPQ=e7t$tR;yFU<$gQu5cR z#CPoyFZ)~+Q70HoXSw=(Fe$CGQ!3AgVzPtq{5$1=D-N|-bgxDq%0K_QZ8}6jUVCs; zwB+vq51}1+JcqIf-5kckk_e!$lo7R+ui>H~60}&O5Nm%Y;E{`8$57EnHpv%r@>}kb z_Rk@hyJ#=)4Z&M*tYha8&4#WUwGi8;XGw33 zG2h_%B*0lb$>j5zGHFdfx>U_W%6wTsdbX2vvB0F;)SHOf<<4jpPH@KH#s=1(extp zz50RzyJl8Expa*}PDgFn=drPC7>18?I+!B67KSCrKbq#%8j0tnM&qDzm>HROJL{QF-*#^P!C?nDP z!oGuLTtXj9UOJ;c943*4?U!^tHx(Ug>GkYN$Jgv_xwr8GHeEKSZ^V*@OX)MV>)^)I zRr)FHbHq|%L6~0j^LfG2xleE_Tu202i$hnRSyi(zIa)f0N_7M~B#3T^4WU*Fc@K)K zm)!Mbr-&r%hd>Wf2E`py29cef23%da*UDx*McF|DST(>W^42|)+q+*>WDMHVS*2G| zHYpQ#nk+kER;fVO9-`dJX1~^j$;?1HVj;`>xn7eydftIkfy*Tj9dT;~WxK;ZN;_wo zdoFc|y?%cCVX&j%+hCtz&qRvIlKi{(qc~<_FXCO2`Ov)mxR=!217aMQzYExnQN4?} z^$Fmc-Hy%X6z;n3OaVEX#HsOBBM%YE%xzurMPWI#hXo2-4o#O8^74s>#{+%#8I6ES zp3QIyKt)MNP9&WvN3m#z%hMOvs+(&r3@VF4ct$r$6f(|LI-@+?l0wGEyHcSqQhJo9Ij_w60L%3F)`9tY3L^kQm@c!ZqGt2rB;iQAv^YQEOR3Yo| z0cW1=`Kg&bd<+(2Z79Tx)@&c61sGZ}pYsD;QMae~y znw}UXzrZlA(f&C)F)z+V_Z4A8CX2oI3K4#ekxOjuU?-|U8TwWe>AUfQ75)v&a`QVD z$N?W>?dnJ$ZqRXU_@!33Wv^vMGkY^06juyvlqqWDTa@@`P4%xv8I<+r(V59rRCZxN z;=Bu+s6r}&U8d?+or`J2>4iE>#xD*xHEVo;Eq831BoM~1@)qC--B;sA6OEPLzkgNs zmDDv-7YSbIWz-?T>H9&iXV`8VBOp;DNi*n$bz|V3b;?6zW>|RI5;eSlr_SjzW|&eA zQrdzzu2Ck5cL=B`O|ztVAUF8Xt*a)XY6)jp#z zYJi;oIwhp#L5T+2e&#gBBXBH{01H!E*jC%YZgbngcCyPDiVm8sAj6tx@BG!3P!H$? z+JMRPXck@+GVu}`ToeHU=lhH|)GxwA)3L{e8z4z*>#j=NG3nKD{4YfrCC&9X&*h&J z40ISPsThzWyycD;M&Ro(pl39GHtt#BY+&R0**tO@^GoCb0xYYBo&7HUjp$1acik7Z zB?kR%U)oD$y2=d_J#L;yifYr7C&jahhXx1s!uYhP~DpL6p*FoH>+gpGQipP;&Rjy|Y_%MhB( zg~iBf#fs0{IV8|LB4$5%IhC4pdWN4Y8BNv9##i+`-hC+);HMqChXiN{hQREI*&q39 z!xqt1U7sxuv>m`{v2oG-B4~j9=Y+5SFlYeqnE$Jw0rrz10U*WXC@6saBuIe$BuIe$ zBuD^o9v{Dd5+ndPx{h80PSNAP$3X|cZSQ|EXyAyr-?(Mv09p_-vw?v*0PXka!9W5W zD^NKNaE`EXfLH-|ft-ggqyMOD>3=I`;Ahv|(VG4td`IQzKtLMvcklsM*NlKy{2!JM z@u%?pv16DSs71%Y&JF?^ah&#Sf&nib2+a0Ba>vgG0y-D`&XvkCVNaz)V0K83&LA_g$hY02?sM!tqbzwcmv8 z&z-&B`0BJ=W8(nAU|84z6XBn=MgI;q&`$+Pk1U=)l59-uK=>2~BhYR7J9PlS28^<@ z{V#FbFJL?E`2D@mf^U3vn%h7?G#(>}^D6M zlq&$js+d`T$k`uY14aQe_rLs@7RPbL`}NlgIHdSu$?PE1-OxP!a57)3=wA3b;k!YF>)(WRgz!i*cX688F* z{^N|g_-xdDoUDpr*NR=I4r-^MgQmnWad04fKz`@s2nhM^-a^e}eKUi7upzXp<(}BG z(Cyb9$hQt&RPK$hPBl{A-K$@Uo^H0^Tr=5YQrZryKUiPX34%5Irw;6bgeUVp4Xfw1 zPz&S8y{g#RTAdoSI2iXOK0p(9`s}hb*rz(U-m84DF_;~w@VKJV%_MMqNow4lCKx%A z9izcu_v#xfY2r%Pm;{%eWj1{)>^rIfdE@dWHy4s@4C)5jx1?M#EDl`neqNYtTe^?j zD2gQ#tkqw~aGy~_5dnk>$B-feHkmt4ZP27zg{x9N|GlJKv<^b=DGI@BxnHV-QdltVVY82xg4zw%%% zW@-N|X%3$SE^ojY2&um*}dmF{`sT|eit8O{e!(Aig5vc4`QWU0$NeDca&17DlE3N47 zVJf<>q+d3tHNswr-mw&~3RlBiyu=X61QLF8qsR*{TwMzJ0mLKrlSb47l=fyA7cB}o zgzeD-lxfqgA}a~(8srEi@V&-GkY(U=3xql+4$)j)bHZgopK4wP%FUqH()T8v)I9l~ zKmt^xmRGzi6ECZJ-JOKX8bG-NdfzHPNkN`fWFTc3fW%y~JAB3LUMu^QFdV&NjQJb2 z9VJg^cRz1q#zb}0)k=&`hM_gwybgBn)M`ns5;vD(+@6=yX2nV3O8xR0giDd49idB+ zLU9!eceyq+33sg61ZZODd#$t97J^OFH-fk(dqO>cGG*KOQ}OfJPJ6*i(wa55=2z$_ zH-dS3^gE?jot7RG7vK^mciRZZnl3U??QO6ZqD|_EAR8ir3+jW zT`kypn8gEUZz_Ej<Db-=-se04 z_lyLbKDd~pNjE4`VEa_^$rQbJdf{D=L^i}1;{1#Y_T=fH-UIZy39rmL_Ylt~VoAYf zaR_BLQXe8^blqYN-b1xNrVFYj7dOi0w!RYD7&u$0HwSM|z3Cwy)XHw8!Y5+k$rCtE z$z_D7UuX7~b_j%?ei?e<$$}%^ig|f=L)^e8d-3OJx4Rz1E zCe1u4m5ZyGn2jtQ3@@GYBD~$!JmQk!Ie`Hxx-}(7@o*19-{#J&2w{2T+v`w-#Ji6A zA(VL3qdK_t5%(%Wv7b^Co{5O-8OQp!95?Dac?6N0KFNvM6c@>zK|Q0;MtX(x)>66kRZtu1Y! zbB5p}E^6on!pIH8X#8@E&Ro~PVI*f0wWS-fq|U~J zBSFhTqAutIkF(gNDv|19mR?Z@qcZ!q44TmxAV$G^#}qIwQ6o(>_j2@Ia@_k38+&t<+D?6ca+`(|ZyXu)#s8 ziG`dORp+`@@z+ta1O zsO?ozTxwRXT~G@BC~I zA@TeH5+1xrvK4SPHD1aJVQPk>ajc>SLXdxY<5MPClU0m9Rv%p4`&xAF@!H;ME#rhQ zXA~)@+VVr!nyOi?R48WJ*fy@np-|JTr@201R10rTc|Qe1d>7;&V+NtY6hfv3C(P8f zE8*r)VQonY(~pwS;`{4jdiC*6;jwe5&UFH12SgGZbv)j@>bb<{@tN#(xPu@F5eGl3 zLsGR{I)U9Nq$wI{l z1+Q5R@AtI{?O#Lk`LL9^9)HfNO!3kaNpn=I08wrkwk@Vwx-9xRyrO)Yp_HAQSMOZ< z08cFFQsrEQ5_Fy8=3d=J1LwMnZNZNxQ7Et;=by9kZ@OsUf@I?mVQmR~Vl&|M?OAQU6fodlCAVJc z0rg1D;&K@dH;Hw;Xgzf!!*Qjvh){bz`I)wLo%0-GGU-Cb+wpmn5IQPIuISGBtRw@PvAfvB@ea7F$oDOt)y(OWB0Yw(18?Yd1T}0cqdO^pi_K*%iNsMjnRT>|nfBRu zQ1@~a-oq?ORAK^7XUNtW3c@@1ItA{n{t7X^(JiVSUIoPqWkVkp?nkTSxTqVKR@_yp zb$x~$0~fWZU+Gu)qWy&l(KMa&RjJs4{w*7arhTsutsh~!#=%W>q1 z5PH44_ksoU=^L6m4_``fWUbnKOd-j-(=KVJVq@~E=%I>EF0pt&e7(f^^YkF6kre12 zZaLZ~MyY_0nuuKE`LKc1(mJ?;T+_P#xM(S*McHu%9QwdaDF0c(JnO(k1_Rq8>kt z#KG|e8nxsD^%yryjflLfuwuNkY8nYK?y#+O{yyv+?B^qeYS%2$wq0d3((+jAQYH9> zvI?5bLdWJT=ENq5KwP#5`!UTiZdq0oG{*90R7IasrD})CqxVy-;FL%s@gY0!jWlD# z8=av5EtEWOC0Q(a)7V~2)a*>5{t!C6u3v$Y=-zOGzo z@rzolG zX$PB;o?*~u8FdXzd8xDH1{E|nO|Cc+&<(eO{p~XlN1f)-@PN9E?H<;SPxyoddrz;z{9~AisRWRw{OH#jw{yieq7iZ0eAQ{*^*AY z=yRNMX=Xn-$RliA^Uu$ia}Ti0tcV-Q$1It2=qCLK8Mh^*2@s2TX^N%;b1ns1hc1?I%IxkLKq8Vl=UNZxm;XLyT~ zmP%S0SJur(BnaS%_3zjg*>9I@Ea1i4wvx41P}?{TJh8UQ50{ULlTb@NdwHNFGuCN9 zx8F%LDi*7L6`^1oJs5##Fm^oFx|YpOsD=WERNeCpgmN>Glxo&|S^R!zMD544IX~W5 zt6Am}n*@z%8dgyM;LQ&lI<`n~8ckPTy=l!El_lkmh}zIyXM0z}5oKnWYEqYlLfe8* zW(;)7%j01n{i1Uh2j3k@JN%vqxOYzx9zGIVYf|V>yq{=Fi+FYaD&5sXSJdHjb8$HXmJIBg=c0)Z%$;r*kF*7&^m0Eb~im+|KUBTwoK)%F}P29rE8E3U*S>abu+Lj_cs~ zfM+06r-x`v?F^XM_cZ)C22ID>4<@^V)QWoynV~PezaH#N!su_i((CH1BbB~Ae zh}#Dt9AY6pfbLMFX&j0De${@2k5b$zHlGYZ!Yg#`k{O?|n>S!_q-a0~*ZPh^n{d$YAa55Ia>EjeHd+M&8D+%;7Y`+G_MfH?y--E+dl*ODR zmz77+IB4onpA!1=^l#$YQmKtfZQZea#`JB4hWsu?8xmQTKoSqlB7DFsGHq-2%i9o4 zUhYn-+#<)Qv|3k44bZ#CqKwGyJy3Fhijfwux*c*e`}2yCX6@BQXmo#! zo?Y{~+*S8>wGqK=M5w3B{<440r(HeI9=S`ZL~o`d+3sqre=r!IU6S^QdpB!@Y!gDD zY3mdo6ar<$DXX3u-iE7}pie;F2pkMm=Iq3>Q8YBqeMokmTg8bj$UEF!j4*;<4j_Ju zoNlguM)GmZax-EnZL~h_P73{Ck7)aS7@oeICeo`xy2zXWw!QbtQ~@86`Q~DkoLL5* zDnHV-IM7uTmVOoA9Tk(xyR6ZWHWU=tVG_5Q_I#CK4o#`3gsBg^j63JtBX{+rUKF%7RbZ==`wzC>@D0pZ8Y z^P^{$zz3Ae5jI{bP~g0xZWuTKGLqqQ7lWNs4i~B-3>S<&TR^E~NuJAfQ`};>E;Jk8{g%j@IafFWLum-gBd#z6hOz>{oHTlHT`>|s zj33_YQs)x^ zp2QvM3Aq%WDdiy$N#l2R9v#KL^cJ~dza*bUs3%5+Dy&_Iubto7Epx5EF^u;SVQa>O z>`OUSvgNxl?RUzVa*sQy-9sj{)qOyQrWSqaX1Szb?(|5aU_=U-LrH4ksBChGq-t+S zhdUuE#)P)A*Nuz_62C(hK!Uv-BE`y>Pm5=7c#W(@2QHIg+PSy8SJNP%8;lVzjJ{;p z%KAD|5yd5*FhB5-dbhReo8v{4dN=%{Jt1cPHahB=g@OR{>$lD_2LK%BbHs5c_z8vs zyypMQ2MLPw4My%)< zfwecWt+cI6$bFOf5gdAEM6SG*!U{HI6hs7eJ!Jz6dT$!Db__&}6XP$e?L zp_(=WfUEBau0d^#aRxu#q;UQBkPAa8D&zM=PBy*$7sDcmHuuJ-MH5wt8wgEuxO)-{ zZMhFQYOBnfnKHXR^PDkw9QumZa2bIRqm`@t(Xu<|dXNvr47aHuclkqqh+pz1zjH(_ zOGnY*jTZZ-O@kEdi+)5(kPYKEw@k73Y#pSL+iP4&9-dPQAxdn!jpp`df2dY(Sg^-=K~lQ<;&r%ppljJ3Q#*I^PryY3+TL z@wBYrI?CFZiO+Q?(qUlA$i;A@Ywz_d%>~Pi6S;AzR5G^nkO}*Um|6@tfM>ejz*z0g|47kf0AEqx;*$@twdAh!Dr%%gXSU_>C9lZ z#L%Ec4t%S*IdYT_Bo0Mel1)kag{}MWRjW2e=4wHZPvC{>gh2X&u=$r^nu{I}(AQCY z={#Sy2&baxr$z__Tubq@z*f_oN&fhnL?ohQdn^Owl@pTXQrLaH3*NdeN$2jEjN5{E zf;}dO_-B@#3WcP*uXa{R^U8K-Y^cN^LX^6$U^156ZM8ur$#+;FzO(PrI5Tynhhvk8 zH!4)DG1z~1t+Kn1F?J*N+O~|oW^d+-pdOB5Mf3V_xP*x}#%6141s5fBlFLc{K1M#R z(?qFfcxB`gtz@R~EeyLf3d1NmpS-1{w1vy=QQ=pYV`E(G<(uZY!rSUPp7*;i1&i&= zR?vLDaMo$?OqA$_fpyH7etS0Rc77T(j7@a?5u(W4)z~+1Tx^Ex>Tw9b%iUC$X`}Gg z9aJT(86?=!%YnS5s;&$x!|U5{BU}CU$f=nww-(BRSf^c2DDhCrf5xt>bqSN46x|m_ zGm@x8YNz(`TC30Thkfyq#5o$y`2v&Jk{Q{EKR{ToX3G9WqzcE+6=MIxNEM(qED%QW zx8*H3P9jq{P9jqPFWqtE$w_1i$4O)gkg4wN%L{(Djm1AG$c0wjALkDvS=_~iG% zC%*?cO%LDy??$p55&s*`BM=ZO@TDX>&<+rYx&W$kFflXH1N|vMz|2`$fOde#qyK@= zO~=&2;Ly2hq-SK~XbLemptpb-FfcPRGcho-G64VT+FILKn9)IDFbkOVkM7r_h4_s* zF#(feV*=uEz9avzx&kvZm=%ciVPyvW7bc}=p?lO+@cT(Y%^84-?@((S26KpwwIx)S zPTvA%2C<lHbHil3-5r~Z;@LK=q51k&wg3j6u0<-zCWCREb)@Ok* zv*_qC>#zZ3iNHD#9Vioo1)>M$VAa>-VAa(JG3l^FP8F2^ev9F6eO62?KLvjPMIrvs zX?0j(f)R8SvG5&kN2B0>TFLz1#_f+i@~1fK6mExmijke2h2K z`G2-w83AuH%TesY5BRaNumT?Yf7X8eWBmTyNB@n}PUCl28wUu!Wcpvk4`>Jd6aW3W zvmWSf0o2erjAr-&KMtTg3giD3{7!rAe=kPl8>gMdkByC<11ND0n0)^zefw|iU!W(? zPyF|@J^t?oi?FlP1C`Z)4mIELAKT$52NMv4@_z%rKaTVT$~=AHwA1_tVgYPgpvlw! zB>%De6s&Y~g!&`>3qDf|M3l{Ps7(s0RlY#ootUp!bIXbfc8UG#TiLfyrb~*b2KVTFndH264|9*kr>GQ|m zMa=;<#+bg3no}JNCMdpiw@+yu<6(_S*jXfm`Rf-Bi}N_2VaRQ$3H;EH)9<%{xVi&= zLmtzU6{R}`~kh25IK*F zYo&A1jziK-8Z6UK+8!6gCN`^AMwWqQ5G|fEPMaIei$4UbS>-j2rLnr@@^zV&A>!p%ynuznbX1 z`XGv!1A-1qDfxM^UBx13p-1huQKYL=DYMu+#Kxp3Ja= zWtl?~4lm5xpO*o12USRxs@lbM$mKT8@?A5XJ+yJ9(vB1gJlyC9;=?)KH+;3kSg%)q zQbn#_!m3!lw6qfR09|BXAUZg1hr5^8Wv_yTVP#xG9-W%a&QkPd=QW?Pnqby6Oy&=F zLNQ3VC>;gJ7u2*c&|*lFjCekC38W=7h|HPc6-6ZH=7b`$h-GCzRHj%=#f^12gD0`- zF&`MeE%o*WQ-c)+3}>8?RQfv5ZvdRJJ*0FCr)FIwW~_l+B-Zj7=9ooIhs9NX6s@`D zR(=-Fj}LKLcc--YDqZ%vCf<@)_c1?VU%}abFlvFq`(W$yoCU2X9uaQ6IN~E;o*m)Y1WYWCP)&;| zN9w&e6X(_$=H9Y=5(3?{3M>}Ub=Z6V_is3E!*Em>=bBV{ECQ~8-*y{ z;~HYWy_jNMq#`0Ny7p#mYy*Y&(cPdcQU|P^V%=vi377|ln!Y-Cvu_eB2N$5{mvIR) zKGO&-uVVMYzxKk3Q)}=l)3QyLERB8?&K+zV7IU@?R~mgp(y%p2z5o?)6c(XOuXlne zin@A<%6e9T&Q|ZW9);lG8xMJ|!Q(uL1?kbEU0HYxpNK9r;d9Pc7|AX?_~He;tA#1a zvp^Q`gGMG$L4}{Dz%7n$k2%JtYP4(K^x#}fjnq$DwzIC}(oaddEwKzm*|k|V;y7B< zRfC5`P|NIp5a<%es-1U6y@$22^%K<6_fwn`x#jFh$U1;@5aQo;m6- zf}gL-1)E-%mC0o)O{HMCJ_JLnGg0%mb4W=nY3)g$Hp$E$$5$R~%Sv<_*@?X~h%Ig%qj^NW0%(T2*IW(A5X}#hWwx1Fm-*Q&haA(k{ z-_=zt;mW>lTllDpIL1?14+>e!!blt{xHEUQX5e!_(voSH!?`GT3fYx^#>QrOej6p6 zUamTj7cqU}ou^8xblO>}5DApH(eqZKpC_D_{Ko^IPri#i`pC&#OH;l2Z}X68OSWB= zeoT|%HL}o2>)v=Rbm%sUlG?7c)J@K}-W_BC1DMz5a^&w#BH8COkQ%7rSaZv8^=%9& zrfkb2Y(R*f6_Uh-&YPO~sveM1WAhDYJj9|xt>~i09@>RI*|muY6{K>iLY}4#je44{ z6r>zjCt}lcJ0yr)KaBM0xPT_VPDYVF9EqppYZgac{CgTb_)mS|?@N+De1-e`oYm#3 zLMDU@g^gsc0e0L7VKyq_6S|JKIE_*Cy>b%0&}>!e>XnTp-`&BvGkG~vw|qLuCutBC z{>UaWG|TZOI;Bhm5mtu^FWh;{WyU{D}pVHrFg3J$cE7*xC|9-bWrm zWpzH*fennqXlI>UbsxX@rUl~j$?i~>mglT#5p<(KDqgI#v9A(bXSdt;VHSSVDSc#(=W#wFFoGOEj8O}gK z^WtW?oKHJrG6M0n&2W{@*r&r>&kcj06>lJZ!dyR_@oxUsJlRJn8Csi0ChuOg)@-@Y zERLLeXG#=r6J99kdG`5`WfcSIW=^wg>1EZtur$T-O-V{i_k9*@Ra&@NzUUC{UBjS? zsZ~47rgKlh#Fk`&*Odf{Z=qCX;Ra+u2`|6YQ6i;%;^JeBf)mf4v{Htc(+g9H(l(OP z^X$J`o0>Okv`i?^H%$iTj%7-Y-m|9vXc(t}9ddi0KL7oOiwzw(`APoS>4q|s4~}Z)U;_=jy zd@!8EuGQqoHq+yW?bQ`dQ*zFgTbGwaOISzGcRvra)fOe#dgHjxCc0hpGG#PBu?Qet7g zL+ve}5wp*xpSdv5qP>qa3JO)yD+`({cBI97WoXl%!5G(0a3DxWuki$;tTE@Oh|#@~ z)jhg%0m+z#AFrYJImlR0*bb7#!J2ek+9s5wdxw#)~hQ=izJRl88FcX*#DtN~Jl7~o6W9~vN z!wiZ8;bm(6O^DRAjlxX0Zc|p#6RoF45KJU z%zKffz_Sz*eBduq<0~y;iM@}?KzUsgga$8lT@x-NDY-X=UALOSVm^Zl_be+G%iAy=jeB+mPTjplQt-{v#a&9ooTRZ! zIOVy$n4xhqEza?rvf8XP&hZcue%@E<4KTBKG>bV{B`$`4&3G%J5VO2lWRy6|tikBE z)>mY)zb|%muGksUbj_TXToc_s+g+Rr_xhl-NiNk>5p5D)UrRB@E7jZ75|4?H4DQ7@ zh(y&~=O{L{P9Feeq3Fq<>6(a^z=03)U`*EBEsFv?k%X`3On>%70=(jKiu-L zGXCx@E#NK(+_S(X1S<>Bp`Do>Xm1MKQn1s50N{Yq9;{64Uq=5YAq4;EUk1`XPf7c~ zyQg4b{=Q{pkX(y-H6v=pG}SJAiXG#*&Nr zU#cVwrW=dmL%K2w9*eKeLW@VTONjEzpY!^YuA5O=@iGyM;Xe?y7S#8cNe;$kM0yF{ zS02;yV7>Sr?4$!*5leu(o?$j&C>SPc+$wP(W;q&jFf-Qyh+?yH~5&cZRhTbB<1FA1fmTJ5xZe2iJBweWFy1DL*UdvoLDY66}zT{EZ`zjB~u9(`>LM*SK9aI+W-HV_B~$VUuoa}rbaz|+xmB01hljM zK1Vc5sU>)j?PA3o)h2u*SO|6--UmY-~-i zFqrZ+f6_bdms_%JS|u9N1L+J5L#fUoJI{twR)=0x^4LiXpa&v;;(m~Dmw7ls3^+y* zB&Cn{ncLfcp03{+A^GU=k#`{o;zokLQ$wI*##rP923cE^d~np9(O_}o2xURLd#2oM zYTv2#sfi=a_P#=W>EdVI9B|A{Mp{ZM&r(lfx&S?p4OgxIrzgP}^4{+^{USYQ$}G(DI=O zxf`;AXTj05fe_o~f*z8cPg*H|)!2|aJKCqH$_0(f1?s!%jL)a!Dx zGWt-`SFgj6Cwy%m`*zAP^cxT=zuW;aX0J(bb}nCy)v6=deAcGsfKb?T#;i)oqs*ON zVJB~-)hvNc`$EsK>!4rsgRdI{}S_U9uB_JKxGZUg+4;b+x8 zSDOVEQNRZjav+ih`M=D(Se8yrcBkj%GbcU6z3Xck2&GR;0)lf9IbvtmtZF(Den`-sMLYgqoW>AkJ_8d3IQ%CnM$Z*EK?j9&~0F4w8y zOvp#(BX(iA5Z2)jk52l=Kfm5;`ld=|y`C3Kz?=T6i6m>K?n~3+Hj15~4Ge5QtQIOJ zm7A^ZXZC!Y3lPuGYsfBW&v;wb1sPZ+(+MwxV~Dan>bheAGSD}A3$Y<1)L8#$@V5Bl zjD7*C2DvijppKGwdB+Q%)B>6tMBX`Ju8A5MMAV`!E;5n10buV=YokIR!N#p2Up`*f z&AAswVhjNhA7wKdY2UsUo=9DmRUXS09Z_U?;-?FPj8~ssk7SJYTr0j*-0=LHIto9^kYU7ms_*;rU#O}kq3JU6--!FD}cUy?3s5!!WOEM z&kV`A&3o-5)sk1-L0)L$n-~`*C)Q(o+vE)?m7~OyUB}07wEMM4Uw|Nz5K26Q`zT^6 z*Y%k8Q=rxw6{p@6hTGDcRZq3u?Jw)`-Sg5~kxtyc@_NGcO+4CrlN?0)l=fnG8aOr5 zE3Y^(%eCYmK-3nn-GZqO0xbON%fyf)}!#oUz}_H zo09e4^&_ybeD6kxm1{IcU_ve5p;<>*X~-=@JxeU+Y$%0B)R4Fyx)<3_zUB7Z>Ncln z&V?}T%rQ}E0_J;3q@?lu=bB@;71KS1!cd2H^?;UL%hjm7^DSJUL6Ii9|qGZ&B=*WdCa7)F;v11F_ub+Y4 zSDsM6T>$OAEuth`LyAWw7LpUy0lPHm%gi~3S`Z}f6zQaXmv>TA-Bv3A|FOMB=KTRZ z-o%*n=tUn(>dW1YC2MEH1S$w19IBfWc5+)#!^$RIX%=CaC_6Jfpz7cYCcW|EJh!9rhquAxI zgaB=%j>(jQIsim7AHOH3TbBy=DPXG*R2Q1PFHh)3R zQT+CISSGF#C$q&&zpQ z-<{xc2WDXm)wLn90N}ARg4&GWe z8Y}A$;^IW0pRhVmn&}6vbM);WNRu}N_8EmWiMa)dg}pfxW=#Tt!61$#rciSO8$%L1 zp!cKRkpLkvGA9921W0r(%&l!;wz@VJFcJ%WlJ86F{lx_T#cl z|K2h)GqTaMbFhPts{MYQ##d$X1;;Oo{+%)bdc1w7OnzAOpOguZ{`1p}f4%5OKYSvg zzAic&P`dGFgX)yg!h9kzPZs?r{c%L^4~YNeqW_Wv5IfL?7z75h9!lS@XnhsgM-x1~ z=s)xQFZ6~i)Xc)}aM_P`HHkft>~m;H0c>Pp0u{0_*Ec#$R{{(J5*rxA+!~^L^#8wG z>0i>$3RH(<1w2AWqUS5^-&Xnrypxq?Ik88Nw>Qg)B>naF29iyF5MM{%{sHOVSZNlZ zQyx1b8{1Lo>93@oUg;BUbiC3h)ScQ}Mlgrn{K1)i^f z{KV`>p!`6>kpw3(Iuhafw&uqRX=4bnAu%$uG=(0TsMbf4TT2%L7*wVtK!0CL3u}n! z(Y}TlnacwlVSek-z%aKsW#k`gmw#`+d|U7n48JV+clwIuM}2joXiotDNuD0*^B-pW z%LV^6sUV;sERgH<*Yf;?#ZL6)33aCz{1^J|i#=zc2}p4VG`V#V>gN z7b->QP-q`+?L&2J1DwoEEp$ytAbNU$thOdG1C+Ne#MT-L>~%V*18`nB+S!0aKm7QY zwLcQ-U)EgyCSQj&zC)aLeOb0Jf!^x2!K5g>|P@qMF>#Ym;`9`e)LK}59pa9V6F$W{)Ryg?Xxf9 zz#8BPa}u57?;N%BhU$^%!z|2zuL3&%gmX>|yrbW|1JN~s0G0t@?E(5h_mq+S>sf+; zKHhBXKkBe=JaN3YznFO}CsN{=Cyw-U7rC9hisesvh*e9Ch zC_(!x`<~JRCtUc&jQ;6NbVTnD&;LE10J>2F36((G_e1gc9SO&J-~^tpJn_@EI0EGd z5>D#@T|+1!5{{GrV5~zSW{3LWP{-T-Khmx|9;&yCx6z7JN-9fI2r8#p#^10rIHX?l2Vo^OY}Z>8+Y#9>6g#@$NT;?X3V+gd-ms? z^FT5HTLQ*ef`0~@0#4$oppzZ+gWyOX0~#R}0~#DQ!@(R1H0lko=OO@&cn6&1!=ENR zB`MJG1@u@w>fb{Y54}S8epWz}lR%|HB{6u~9>*=Z@?-457{V;;umvWN zpa!;>W9Hw}6(kl&JZDE&ci0DjVSHEwYy`br-1b7L8f5<&Q3rN`Nx#V-1kBTe8<@eB z;E=hZODr9BjFYI%mqXPZg`HsHP}uQ|Ch>CP09sZ~R!R<3S>e2bP8?375kH1md2opb z!OOs}5V$-(prOGdih?vWB7@`47|n+1)>(< zqa2((f$JejHCa6Dm`amY`+yi?PsiX`sA#%@JsnyRLG>N2(&L{F`ZPfdNX3u=2|969 zX$o*GROr4Kf()R+h8)U!B;G}-!+k&e3gP=%i6J=&U`Q40#83nim_!m_$0A2?EGR*E z5=iQ82Dk(fDja}Xk%yqY1#l%6f{qThHc$vEI0p1za!7KbWkClaO^yb_N<7hHwuRB9 zpob~w2?wlidSkHz0b(XKgFj7R@i-usQBVYTt|)+hDLkn-OM@N#pb#^;6qsJZ_p^c+ z-q}75uLeVmu?LfRW+|tVWHm@80Hud;q-bpeuF0?w#PR|-u7smZ$c11o1Jo289R(d- zK&IgUGEDeo7dWZJKBtD{6OQw37qQCMF8U}s^wJFnj-E6iSk&A z08>a0f0_URsR)ph3LK3TNGhQgP8_Lt5kQ0vvocK12Bw$r{o@k>S;*P24j(c0&_#e* z3rL&|K77PgeZg8A5Ked-Sh(5Q0F=G#ZJY(stPkm?BoB!N!D6Djs4)s4$2T>hM++ zdWG=)EFp%Ubevfu{D3%yP?@A0W(t7>Jj9>^%dbkK8aipLVbWskd{IUR+ zoK$EV5$n_sB@Oe?po15e5rB#8zX8i+KH*Ojo{Ah;Qc~r>dIH72rGBU=p}?Zl;edr- zA$PC(3zwnkS~P|@%0vut#CD;%7n04f3cO+G!H77C=Nbp% zvf!kaJnBUeM`a8{oGI#s>HWVDmjPFZffO5>p&{5D*wn-K%i6@hmSiA|+I4BFpgavaFW5NK&i6C?Q zZ&4>*8ZZW9(ty_W5c7}R?8{Obn9MKZ&7O$xlS%^%TB&lN+VZ#4JyZZOabSv&VS@ir z99YmGN2N(g%aI)=Ao74R2(thrDgm*DKm%SLT;RqPNcEi@?0|)bBLNFge*qP?u|ynT z4N1X&9Ne&Y2FT`9!6lV&n*p;0z_^HEjv536bL7@$R+uAqIpbX}>{kenJ08qsWT8c3 z(8^k({$VBn5i=BXlsuf#XS{R~5js{zAB^k#yN=MEKKzJy8^9#^Fk1*rpkrXvrTj>d2`diu!+7^jSOz6OxaOZqQE0bJr?C-`;{@t zW_0#w%N(BXkijH8Gdb|&OqT;)#z4(T>Y6CHkuB zavJ^~=pmcL$E+ZU_(NzajOpGUI?u=cp$VPRkDcQK+=&Vgy&G@( zabBLBrT-E0VGPCKN9_O#KWhImDQAQqPJ|d@KE@T!@=c|i8yV~#-a zuLV40M?PK~;ZGA-LGB1Bq*(lC+J}lD>IhKs@K}&|B9`(%P6Jhu0}tLmn0=K2PD z8me2Nzr;c?$R8A3`3~luq=9UZ3I@h%Ofb+w7h)*j{t#RoL@*SH7s2BKeVV|N@dyS5 z9Ls>Kioq!&o>rWnKxGjV3|P7tBolgtK)^T!14IW>V8&YkKH;H<(qn>wGKel1Oi>Es z;#0(08bTc&P!Z3~)m22ZXbOGuqyR_4_bL4VWzh-JKSW zWDOr6s0L5YoD0f<$^b=120nYEKMdU}VC=-ehyMoMDiBN}0er-V;K7GJP2fE__~f)w zWk6{_8uVF0-%FFwj8asp#RM1w&2%0d4_~<(xr_o*R@Mx?DgSyfkBJxJ0Wk9LSd+M*abisY zZLsnRkP9Hn8-g{;AQWqiB0LQwUI^cR;|``c9Ic^NUT`nVUJwmhxTDAM;AaP<#}6tN z2-;dWID#v7uug7Jw1jkvSn!ik0ESamkp@@x=|&6FWsE-b?3OBxsy6K5sqm2-YkUzG zfPXaT(*!YQfiL`7BCV|T2&n;JB8B0LcqBXlBwmI!zN9oz=XcxFDbop zp#Kz1FoJg`jMCyW)0IdOz{ zK;RHtjgp5WfN?Xye`NYd>l;zVD4>%R7$O#_9u?bEK*yI!$YHh+m_Rtog`KyD2WYTI zoU;|^&jvv|8oohYyC5xefv^WhkxbabTUgn{i2&T!>*(MFW^n)Ny~&?YMjjkm zDS!$pq>Xe59+L>D*ED*R~zGsq1QFL@t+!x3Lz#D#CRGZ zm_PtajVGr89Pa+*kPmspF(U{9QNUJw0fGv%g+K$C!m$UQbbiqdKE@!-Adu()iPOPyeFRAfK^sU23}IN|E=%Nf@He4KfTIua_K+hGgx7HB zp}9TWd zNk7PTE9l#UU`Ei(#=*`WoaKW-O-TPiSDppb2jJjr<>KZBZG#vy{PfHor~2gdg6jgM zfHhNOY?T_r7v&g=FE$B);EN3ru)vqe@WP+|Kk$XNH-J7AS$GtSfwyR^hl&)6FVjQ` zm<3@LFqZft1$?4DfKz@cu*(K4$0W)a9Lr-2!tiAla(K9czyuu|P=x_4muNxP(!mbS z;K4*EbjFXwcerXF8M@@uQoy9CBIx{wXNc(>qoa%Q3quzzMWN`TVIToroVxt;W(65? z>Oc+&rpCbR7z7KQI-I^@gD6OBhm<4n$szm-ftRfDgjJ7-Cn#`(+>8Q_5{Wb*crsS! zu+bPi6G+^Nk*eOdP1`o$ln*KYqF??WyOF5!AiRdYT@Lf57(S>nBKTkjau`0C=poEv zI&Pwptwh-BVhwfyf$+h_+0jQE+Vr9A2Kqt-k?0c)2ZDA2Xk6SIYAdj%F9$$YeSj?x zkjb&KKn|;L?IuvJ3D=q+p=DeW0o?@4iZ5f$lYbxRp<>%0P(fvMGuVI}D8Hqf;jb%14TSb2Hd(22^aB+ze$rZU((6n9yDd8qtB9kyV5fcm~x$#FpS@P>OI& zAX}TT%>_5GgA9wpeFmVj6z&(rP5c1d8F9s9N~&mbAY=wbWkomvp;J6&iWnUYwgmz~ z7#kj^TU8{e!w_b2G-Nv&$YV@$?gEP>B@btOM5BN@8f+&6f-uv7J}_$Fga2xn$Z3E& za4692st`Bn{G!L07=tjDFpD|ao`kIqpuZpF2xBdzP|F}VY=jim(#Hd=r2$RhAY#Ot ziOoUAVGWWDXt)bq3*%+)0BRC$p3d;xp2fdz3IP{Bg9l-%HIZj?bg{q~jaoo#R|F~+ zj2?=p_=u3;WuByzM=BO9X#KC|GAg#Y0Tm0TIuAU?|Bqt9f(BVR(Cj1)$tJm25d0NN z5uOPo{>or%G*iQ1qab#^JSHVb=QwHyK)<<*v!t($8#tQAnFMosIhmDZpfD`xquWy& z2m^qeBUYU*>0=^*mPauWU~q!iR6eE#410N~=tcqj(?g#oAV4kx-SymS8sswXhj0y7?#3<8Hh_TfVh?Zkhe z!}7SNBU{8U9*Cjj9;`B;GOnq@MWxuD3Pj79rt?8H`2U6&ZfTU3k!7sF(~UpIAdDr< za!$4+0S__a-63@Cz*zwZ?%X|{kgif3v|~OU+?)=cY23yeiF~lKA-pJ6533s?M-O9S z%BZ>Mt^ho&kQpE-4hvXGX$9S^&^iFZ_!16QZ0!OHD`H6T1dw4FUocijh7JYkJpq_DGi?3&Ps~A&3s_#H z0CuGSQkbnZ#zjn(QO!nG8MWQm0}?QYd4|vL$Tl#H2XhL*Tv|b%0_TZzTJe~p5d?}k zLLMG-5_d69%t5mRxV#r!ivx)d0}Tk~D1$JTkO)4+76Rtvs_X%RI45^IDZ~*Y|8KD$ z9Qj#Tf`|=g%0UMyPR-%!B4JdFVLBUGp)p?VN1ueQ{ircOB!RGmfe^Yeji*!L9R&m? zkV^tmGhj;d|6}VH624q6Ich7gB?YL2pkW`z4n|u6uPb0UQTgW`4lHPeZswH+r7~6%{Gb&QJOsc8 zu@&fw37oAM&k_f4Z8!ACh*C;})@I8ofL(xie$m}N#vqI(%xXfm#o;d!g2P?k#slgn zbC)s)Bc+%xF|Y?`3HC0I);O;~PC2+O=r3afblzb|qh=RHnqUG6NHZDbe_qwVg3F-q z=dWV}R8+Vyq!IG)NJFm>^pK@jAm^7Xpn>(+08kl3*62txMI-P4J%I*1(n$CYE%F3T z!P(Qv5-Rf9;x_$3cEQCN+x-WAixYiOM!tK&{~NXRJvkg48-6@EEzH&2zKW) zJ{u$4Or!0fv4WY~SQK`U|8X!gh-Ks$MegvstD)IgE&Id4x4Sg*U z5fG69gT;Db3&L@_xkt&vNd^200g-V^1!xNe<{q58Ljp#3k92d7F$gmP%&PHUTOSyV z0NB?8Z`c|$1`NHy^m;v^dEnpSr+_^g^70^Sg^U;dap*>YaX|z)BSoYEg`Z&X2=FtR z;D25a!2*7;eoqQaH&Wqgd^)YT%m7?vp>v-*q2j zC#L(TDL}zT{R8%-1n`**@;~p0pdbfmM8?a3{ziFlxW?$c@Zclzh6VuW3JbjMlei?- zx=+e4Sa#7rfUU zLfZ2F2vK&8Q&WxAt@d`+h)(kDKga#2l~mEFOS# z>)06JXiSCyj@keOaKe%Yg7sz^a|bJ=nE5>(z~M!KU?u@Rh+t4SOzF`e0s)+9$pdvf zOCBiX{DMw~q`_s$jJuHiG5^gGj=_#H5``VxV1U9-UX{ZMHT-_UGm-;MP8~=Lq`=rF>vI~c?+FE( zDJmY%QU?k-4RRn|r?Nh$!B~O;%`EM3_Z5K&o3?4PGG{*6%3W2Ss>&`7zW4S zJG;d>^M7LFuI9%-}t+A#rk?(OG%CQTb=@LEcRDpWy<`LpshVc{l>#SN<7i zQhq_LBVfG>$%ny*v!J3B;h8{^X3#@?3ow{t?Fm-+f$L(&HhfrvMoZ|P7Jx9>OeYI&Q7E8^ z4jddZuA>=47ImZ;valv$tvJ}gHYu{;nkw+@3`ec7%^)zA99d)>lSx}xo`zr=i)NFk zXd#vn&s7q4z!F(<8o&`7l)xjMx(w0g{nP(q$} z3{H}|sw_F3zzRzNyCM%yS<>ko!xiNef-C4Ufw4kP+GyzJ1agg~!ISlPT#-)`9%($d zLgyLMGQ=*wF^$DU2`S8ARP?&%6$KMUgx)^f^&sSK#s0{jS;rciaN8)Y#14E|a-%uy@zvN{jJnBe_hM|r)6+8hX zj)J8&BbS{rS(LvvPS6=dM;)OEPXkFJ0ih0Bp7jw#ZLAF->|ivJ#VUkfAVV+64Jghy z%kB!U-Gfh9u#=a6JY)s?)*)pkJ}T&?0Q0XDdB&kB%phP|O&1N+KA@t3ntc|Ao@i%j zaG~R$M1!1GuqF!bzhj%J@@d#eH@PIB1O7NBz@H`nLGBvJY5lL!TpG4S0g(iz zfq8^r0s$-~ft&_88aST@TYumwP-fSFF^Fy?nACx6bAh2VT$clvszO#D6i(10EI42T zw_)Q;@%rHIMX;G^tUL!+TaYO@SQ7(Hxq`k?@LM{WW3VD*(P2f6E27}oI5rDdnM^Mn zRS>v39#}zhpA;yT(HNV7akd|oB-HjZ4Z_plR|o`*6IK~TXdFTsEH%ONi|+9W>nV^; zTnt8rY$E{*D>(iJc{K>nwYO=QZ`IxghGRf1heEsow9Ek&-)Q3qZq~%Z3M<|?wH0F& z8pvT=6;N1FE6xH|#H!=9mBgE|fR&Wi|01 zJe-D3*5e6)2qv(Sr6p!TgAAya05Dm=i7^O+lUb(8778Gt78pzelcqkdE(o9~f;bf= z*@*y#xWFSZ1<>GSPy+)al#tn>bBc~C#wQF_#Al)zHFo^M0#znENVcG0Jg8E@&5epO zV1FD-RMEN)Vu(@l@Tih_f^nh>cG^nOz)B#Xh`6nO58*HpvN1dz^l5_Luz(o;9ws9L4&iCw`Vi($64VYeY!d() z4wHk2n8XpVhM1HFS!m%OsF$(`p|Euebj4+obC@jzCLjmf(BL@!!YcZbYW(rG7q}S~ z?6(4O*4R!vymclengZfJd07QHcu0%{WQ0g8PR8ct5$jA`C_n(2sXXw{3k6sRqzoAS zp@9=Vc!GmYE6zHja)rjpObZ3Th%~d5u>=|Ev?U4}dAdlClQ9NiATvuk*+K!P^heJI zzz8mu^4Z`C-ApqUEo04vI9yrK3G5B)?V>b{Q>gMXYy_Yo699B$L{wfl(8Mb*{Aq&R zk}EGctw3x4x?L1pp~PT4m=Z9UU;+W-#1-6j^Ow5=X&8g(xH1bjvyWI~Yh!B*VnZ2l zUI}*5g3)boF}<`j%@+L6T3VU{_WaVovR|4F@?ZFO(7(a^X;$cK7T~|oXTh7{_k+*D zpNIYq^j=WKg#U|w4|pB=F6jN(_dab_kc1h{2u7NRE%cm`?1&2=b_ms)Ay#zl1l?{IlxmYfaOpCbh?()BMVFx zFv&#?6l#%R8^=;|nXEoMuM1T4~Y_XJTtwip{K$HQehP@{DP^KFpZ@c^Y> zxQWuj%F4wPK90k(d=k6G;%WZc0S`hF#1f$BV2xAZ(eI^xv*}_Bv)V3t(1O^{Ktqp39 zgoYa7x~qqa3s{KgY=?6|}e+11%gJ8sO+F>j4oZk0|^mKAb_PBBViIzjlnWga6~DCbXbxA zi82TSl0=#zw@9D?pTz?W2A3S!LU-PvMH?K3lp}x+>ODiUyq%)%;0LI689MIJvT?Qp4eTJx z+bISGijWchORfieJopMG?vaPJbZuqaLI4`}p}&Ehf}msm#G_I?YoYfO9*a~zSy1<% zl~k-}6TucG2uA??3V{Gt*s`Dj^eaQN*$T{)?FhCgOX&K^B;aIw2f)dhx(qDppIlCxJnz`dSL*5g8qynv_g56CYYA7QHOV+0SQ5*Q%+Wf269gOHeH-t{nLShN3w2vA>bI;ZEJ(M}cWN_S+B?kI-u|^r zo?28GU;Eu)zuDQDA!BvyPBPVrA)q4-chsCH&sycXb zwt|VGx%Eg#o?n^8>CPsu8)j3I&&)W@m985X<)W^fx_eIj69EGS4u9K865CCi-c;)r zu=k0d`r>@CF~0N88|g?t|EJ;&Mb8=r)=h8S7kfH;!1vv(P1T3K9NLqRJ=u1uq=dTY zHU41JFkR7i#%$~tMM~G4xg7s2%Xh*_cA8LCtMSa1k4q~KFBd)LYdqQWoxCbXnehxs zo#UA^jA!O5Buv=iYR0z6wZwk;I_`8E8}|A*aoK>w)w`9|?nsoH%#{;%Ui+$*qq%^$ z=95^<;TL<7995me9^@X>;I0p`30|7Z?nAjS%x!w&V%OuGRe{fpuU%T3Y#H-Awtq_T z%y(keGUa0TFO)wD2y^2%bu1N|Gym}n`$IH^X&XK&_|Gyg`qe$RFR;Stv`t%Ii5OpF z*c{$=qb5lOc7aDLx_Nd^5ZkmOAyVb*s*GnD96h`dcB5Ti&-n-xi58nxU!HfsifSr8 z7{;%Yek9OfVXSyX!MU>61~EO_>CO5>Ys;Iz^&Xp?J3}G7Jf_;ftS~wK-gR4tEj9;= z-@l)}MLd=EI$B<)HCK;)qwTirl%zHN<*&Pcgbu{)M3Swk(QS)7vW)_h4;1$QSM5u2PI#4SCC@-oH!uOGD`cu*MDZyYtYU7J}_VKT`y$bd)`s!aWQjpN!Hgx~- zcCNYv8m01r?G}N^@0IuI`Rec5^)-BJ?Vp8pJ-y~yck_O4*isa>GSs!WZo|NzEIxtS2O}Sk z)#bT-*I#9*2*A80D^9zHsX&XD@}%Ck2n@)p6e%>^s)Neq~F0mgjVf zywOsQ4Gyd0oD-|tU*6hlT0uLd)@|A^6_+R5`T1wZrjnKw8)*R=t9?8#im&ols74$oZ7E!^~p; zJO8++693tG3BfYM>=tTHr5aCu&65D{LvcZ2t-F ziAQ(Y<(r3{&P%k`c1-FsyQLUCnEP6DnboJkUkTnHZ(1ei6broaSZ;f=Ha%pz($Y;b zU7f2>`;9)DOvirg4wKx3TQvRp14+?tQBV(t>X9H{KHO{eZfkT zY1iI#e3@n3fAwYj8}rsVkMHO&P%#epoUF2A7S-DDOjO{@y#3v;=Gu!tba7Yw)))2U zhU2-%R=?`{_aA)0Qz63dBwww(bpOit)w!nG8_M1;lS-P!yLq8>=d2mZKje>}Et&6h zP4u1m%4Vm0%c+!U$My|3+?K8zU2AC&$m?)?pY?&Ti|bbuY%3_v@8eqZJtH&X+OtMa z(N*;>l0$di?wPwb86tw0;`O!(H-A^323hrJx{y2dvu9kV_L4l zqquQ6=2HFxh!*;ap1Wq;W%nOog7%HesD&1%+b#QfVbV#VWc zH+?A9k)Ag%uU2iSz5LurNBB-tosE^Z0zY_#U)VHpVZi8)MB&F7e@=(r+8Mg}@fB-} zGr~1xHb*$>g`0 zIdu!C58QqBxaXE*ua3(F%_7+uZA1QvHFh1GQwri5d{-ybJ0%^|Dma$C;?~kZt5;Kp zx9Mg*iPi1(a9qY8_(UTvt3n`2e&eI_V)qODx*k4G?y`*=xF0j)+`X_RBHXuDeAp$u z_wBd5s_YlG+1tvWzuuE8B&Cw2TN>oKLO9eT!giO@y3Vq1uWUzMhwN)#U;j~-Z2Ecf zk%s6sm+rd`y)KSg86N%p7O(O~c7d2hEiJLn&Xy=Gs514kl9IeU|MUjis5zDo_1wOw zS2oK_st(iS4oU}o;`+kXuzIkgd1pb;{OY9zXQYJQMTwXnC}{7t*b)(^qchDjWWTD* z=S|0pw$@x}-x^v)eN`9i*h`a~QGR8#vq}TaQAz$(wVh*WAKR));f9ULS z3DwAAkK-}Vwf$Yfg4T1N2%6t9|54n?Pm517i)<4+xJq91Exul~=FJ=dr!(0@mdh-y zN~50grRgTL>MciC=dC|PBa{Fq!=+DZ=ZJYTX&>~eruFs0W8mE5kuTe$rmZ?^>7`J=#6nC#z$QmB=4ziV=e4S?TQ4Rjl^&kq#pXVZ^T=hV4-pY_ zvrjD9fB5^AE}N(Wea5p7QrP^$%iH=C+&Sco!bWdMMrQc^I4LK$%yhk)|EV+AwAA@e zMU=jj4;M0ut@-3Jz3;l2RID;j`%a-9MW3E=*YAI5%O|0=I$gMK?pnTzbBVR>uR;<_ z_x>C(77jJb2|50{vs(PcA=;(>P_viK8d~W!sTTK(+lxz^-}rF1^?$klblaDg%feS2 zRUbO|rn{_3c2Pi4Z1ICciQ=Q9)UwjlnCa)EnyPkN=Bmf3#x{Omzjevaa=H7LqDCcE zsoM^oySq|8h2vv}(bFekB0;Mw*|SqrI?uC?xXbS^yLrRqV+mE=E&Xiwg23A zHSNKRY~HsKMv1N7uf9w%{&4E6yHBOIst;GUCyXRzX8oouQLa8cW9VMVN3KMtk%_C!oYZzb za0-w3pc9k*b(gNgviF|%JdS1w(tLi2%{7~ zT^d>ilLsZ&2W;N6S?i^)nuQSc#mX5~+(%3ac!y;lz+iVbdELfAWLvvsz_B zt#5k=HAMO?QgpC5e`nwImtVR(nnhYJn>|hDDt&mgMl*F~=_iloU7_lJKXUFnXOvn! zy3}KQkAHigS=b7$;M38&jMViPu=AFjs|lLmLV2!!qA}xPmi_kT@(qbSza0<0TbRYx z$KJcnUo%M9D&e%I#}Adp%b$09=BM?&eR9WfwbANpJ(=Ey>KFC}oqYbar0IFTw@H!T z+W9Z9T*}nd`yxf`c4xUP@ zN494tdU@Qg3O4GWJ;Z6Yt1KzU+POKcWJS>8%dR?yZ-$)u>7}%EyLtFW)#!ZdX|cb` zZ=5du^rMG*H|+Sa=E0vj*Nj|So9=GhpcBErzFb62xyjCX;kE)^&n?0yzaOev^7Px6 zUbf%!vrq3sJPx}>VvN@&dNnNEx5Pi@wSn)#)U6GN{_r;&S$mmlc)2+qUyqe zm?wIvJ-L&#e^w7(^q>}$RSYb?ax=BsDo>YdZPZo`w-WB}8#`)hZG^dfWn%exdC#>T z3RizxoSv!l=v|CJoH&=ja!&122~_dMo830F!IW+uFS!S$sUN)t=4S+d?OD5vBdWV{ z*UcAK4=)Tov{G_M=B&OlujLVKtqXE4lqLHHi4+F8zT0z0&#~XQdbiSg&8rW#vaj8p*83ebnj5a$TS}@wr7u4&-iNCTRy{D zWqrKbYIemJ+Bt;>uYRITYq=V@Tq9xs=SK^Cmwaz2y0l7k)vOEm*VzAj^+$HmlcN@G z?OBW0U3bh7K6^jg>{ztUW#>(Id&PLK`LBE>YR+><`RhK}eU5s!-dyQlux_ol1=qc) z?fEOYuay1}58CIwy>s}LK|c3jYx#EGBc2y`a_P6SpI`2BxWi4UB4S5`vbnQ{$pYsc)nJT*0f8XS7Jgo~%zML?-fy-H5d0(W^f>@0XB+Q!BzP(rK#a*75Xn#q2 z`;1n5I9K;}8OJ*p%`cK}C;X?hP0+i&+v&0C)z{mT95jtj`p=?HSu9fHqUpWi&(Qv$ zKU+Vfb?5!e&7a#DrL*|JnMdGf@A+D0Rx|$0dVlm~j-`=Dop_B^WAOXjE1X@K{i0RL zPxHiw!}-7yi88ZFnGTw%`mO` zx=7EpR_eRkVpo@ZJ&@u@{aImFnbKjlX2@P{?ELhb${$P z7qVY<(h85bv0UU2_0CZ5h=|waK9_6zZ{Oj%@pNzDyoMQ7H#cWl?mDLTwP#ixuSl7S zXoh}wMf?)uud~gMjc6X#wtA(Ue`!S{FEhV7y{InV{pY<|@>$^vns&W0@Qz${$Zl|x>!Aep;eoFo zc?&fM&D)LE`mY^`99>p8w?=vTiUB!=GCS2%rYC+Bs&W0|?n?;>b`DtlQ^DxeVg6BS zXU=RD?lbxATe$a6?)>EWqU4WKdInp9FOOqOs$iIJ?H{hlD8s8Wz%8I?nFIU;)k|pb zoETO)K`J6Lf?)TBJgBezt!knuBcsSrHTmX0-PoXQXy8{|mt#(sY*9#s>lAgJpo!e) zc-h!zbL^B3E?cMjvVNb~-DFAI=4jJakROYPxNs!rTPHij#P~X8-Fwr2yEeBXtxn2) z;C^Gw!gZ;`2Lq~p6jmJ=t!i{vuzQ|&ziasZupjR_ULotiMJK|J4zek$T@>QG99VkE z%h|%DW8=J&x26rIy`aqxmk{_}oAKw+vj@&E;&-j4NLqc2_0tv#s!_eWr~dVqgxb=v z`tr15l+%a0<69;uCC_U56>oZ=bXNLI=b#>?-4FJf_P_3V86GywT{hJ_-?5~xpw=ns z#grnIqv2KOsR5cFzO!GF-y<8AI=hV{{6l74R$`Y^@I)2ClOdn?Nvu4uaAb{F=i@K8 z#cRc9wKcpj5Mn>dX}ltR+N52NF5bRz`{pAZHoa>{)@=4`Qs(7;&E;JsD7;xMuSjq0 z(83|q@a#YO?2h0#+_fvYfO+b#qW=x zl?CQI9~$J(4hRg-(%3n(L2RAMVNQ+h(r={=P3&a~J{4so7FY1fO-eu9X)R~kG0fdY z+51wogVI}dCkLlSwl6y-NiGQ8u=Y~({fRu6g;HiU1c|@&e|zBQtz4m` zu;rHxc>5DA<>uWGQMnPQ`}*zMpAMzRby~&pRUf_?l-}=q|?Dc+hb>Y24np6^VT z^gg3Ar}z{ty-hk!J`RqaB_<`_$J5%*!QWbW-=gWz=!n~p?XPE>yW-xa+U@z3^d!hx z@1BxW*&YgC-|Ca5A~V*M&SAe|U^KyqXUfLF^48So8A)Ffy7R{7hu~W8s(S;7DgySdEC)!WY5V|vIMXyK= z|4zkwlj4n9w*(k9?QQcp-&?U3nr{0hpO!ak z^>uShC!gZ;p5bxMR<7l{{O-2H9cC{wVpJ2u6OYEtH>jCX7Hl-HRjI-GVAbp9LuO@0 z!8-AiC`IjTQ`nOB&JkH6=}x`IpJx7`G^AwvRr|e37ryKepOnP+_H9()(2&SP{mp_V zWn9au{z%N&udEy)-nL+hp6Kh-+~2%6uhwavaBlaRo&73;@51}~i&On>JYMS`*fUjK zV6v9kgi|T5)sH(So7L0|FFTj<;Kl=A?YhLQ)8(RXGharwjc8#jab2cDg+KM?1vKYTG;g-^3+{%%g!ci)m7 zjc=EpC|NI@Y45F(@@>6UoKl3mWU;{R8=s#(d>V4|Vz@+T*sWC=r`O#U5nlOavg7)F zCk-YnHs8L)SZ@BUy%e4>>sg-XXr@ffv1dh0`_Z!B%9JT}$E)7X-& z@_zMh4NsnFj(QK4R;;@qC%pSCd)}6FrwyeYtdC|dyC<=`a^|HQ`#u^TzBQ>heJ5ML z;h@kQQ3(g{VzX9<;SKJ|<%5A!ZI&KXj&rPpUl3GJO60#AB!bd^9-oIOB6!O6ciGy=UEJp${z9ub(_`ajcFj2k-Sq3nxvU!8?1d zx)EE;vVimUL7eBf_>&$^ZsMOkM?F8R$o1+u@$XF&(`R(5N7k;>6s$FrR#sVa>UPGY zGF{KIm7(ie9OgE)@+dY0czymHQ&yC@GK_b7$eHUJkwUKe(t?2jpLoP}ojIp#(6Ni> zmG`q%Zwe-T$evLkU&ep5+`?9L4OjV|*M>K@RZOA@$0J@o~Um4uCAulz<(mue!71~`LyLXc|8u~)NDC<=e7Xb zQl6UETZC7#i{?B`kZ^r|Ex#gV%DFJUdRd;GbxpR@RTS>ko)B1UVv@DsQSjG?x;#p} z6|IIGKjpoSWQE?B3c9y>m71T!3a5PgBkTDla_Gi%)qmBnkEE1|FWKx@&mVS1S?1NT zm-%b8QmS~@pGgtyUCOTc?nQ_^CHAPY%L#BI-OXO6_U>7@q{Xr1*50Xo zok#3b9(`t$d~0DRo5pw9qwC>`3x;NP_9aWtf8@{|*zGg*OK(}|f?Ly~#k|(Zo#($K zrJF10IBg|cI^PY^gS|CxjRvo02`PoJ2e?kyB7f+7(xOAN%@*lwX_-1z?$z%130sEU z)kfBQTd+x1hJ2{+~`|h?v{HvoLMyMD*N*1 zu4P5Mvz*w2k9nJiuTAk^Z5k54p;7Q{NcU2uPu={#b$+BoiiwH%1<|H)-^h-gJn(Sc zqm915I5TE-bFu6Av{mv{@@Dj{GRvC85iU91IxKBkzU7F>VLor^5?bBM-3NE=+FW+N zpw?aQvy9SJ=lz@8)f_ZW9`*>%TROEMa_`~c#py?t_IZ9Po-ef0l;h4zjrU*j%eVU; zGmL(FtnNYdg1iG_E=S@;eg6CrAN+dJ;HA~Vf~g0B-d;Ae7co7>ul{TI3Pk-RzRJ({pMQh9Mm&bYwsKlx~ z`cw2r@X4cE^L+hj(^NwF6&4(KIiYf0&p_CK!}UQ@!Ha!2G(1oGW(@glz5L0dQt7>^ z)0Lk~;!KQ^V^jQ0ew}!b5O8)>|44(*-gkQj>Qks6tan6zAMHz!KXoO>0#9U6^66C^IC7G;0e49Z-rW^wV-?4{*r zuUD>3Ek$ctmTi-GO6Sgi(HtsuTr1uW`K9? zr`$#7J<=YnNKjg4=YP=T`wzXj0VmflnWmG=os!1awDi8})^|y%mo0^bHy)@kiP1V; z>TG*!QH`V7&+aeB;uCkbnYRY)_|?*KuCR0k*VI(^Tt!8j5CsYAN=85*}B59_^Jh zajp~n&7*wRd5K5H-r;$xG#Z6CLVNdk2i;oDBi5hVDJn0rw6L>6IeymN%Capz$G@_F z>RTkIP#Pt#m~lzaC1TY%y*(NsgX0R_NU8b=zwj_ELo#+;DLPqY&cPngHEG*Qi2Z;ch@!rFzlY4uw- zbJhKb6<9Uu-7&mHB{!fx^J-7z2EIHwX@O@a+I;WLu6pFvV$$2t%QqPDn|s@%k&jvt zRTJMt9H*2X=A(Z3M7=S4ewJqWjVTjTy%)2!#=5_%P_*bf)F2r{$?-AU_=x}0fPSLn zkGL8Bjc#xKyBv39e9Lj2u`cbfzrtaq@I>9v8t$WPGqXR-ENYRvvE{es#0?z%`bCjW zijV5t?&frJXl=JmoX7P-EzNd{qkGQun-N*;wtc&NepPDM7~I>}(R%JwTqGCeoYBYO z{b_#otrxFO-fZW5z^{}t*lXT)W$D=`yiKWdMK`YZ`QW_GntO_RXV2;few2Ohmi(Mk z`1ta+jh{`MwP(Lho>N$Gq+E1`_}0PC>I-l823B&mW_}-dk|c4rp@p)rK`(m66>X(E zXUyCjs?`oJAMEPo%HeA8uk$k;kn*We+Z%u2z_$j&t@;}b13bI#E~u3$_wwNRrc`rr z)OhoOHIhqKSoPo7Adr6`AlXIpWA|gh8D}Qd$5t$v;B)@v1Q#ROYnHqx*UkPIQXHx% zEB`u!GR;<&+xwN2fOhC~pGV95)>veVL|IQtUjLYb66HNHC#p)ByTZbBl3m->HHt_!Bc z*F+BtHfE+Daax#G8JgsM)T&7QijvvJ?0hHZSI0UA*|tAxZ%z2#KjP`%lzFf3_6kiq z*)BG(6|W=N5(GvJqPNKZ>XUPRv@ol-;%C2G))6;bPMx#tdbwAeMH^QZpOB{eZ$af^Imdb2fb(Q0e28C9$#wSa14Fpt^#fr4~EyK9o7h8r1&aq8N=ng59eniWh)X82L zv`<1dxnJLH>ANSz>E^$`igkFO}PRsCZtyq7IJJ-hjy(l#~nEZh6$>%vs(4E2@LkEB)HbKl3f>!r_;VBa-4cXEw=rG1Q+-BPR;)nFUd9H^K@xr(vrENZJS$n?=3o3m%=3s!<6|4N|)z=qKTs!&oQB=)0S%M zn3^iQFqMA(h_-XftecIe)tYGMECu3!gmm(+G}1Hea{STbmmeoOvn_Fw%e~jBrydmU z_FQ_#@y)O1dq)z7e%ee8UCwb)Y~R9VGHj1*(n~K!MX^gf?^a*B+9vy2gS=i@)KbUf zI=9)ehA$T-$Ih#w(DvBW(#+h1rkOU>FHBqbIKMdY{JZ$j%G@jMd!BqhrDgwaf6wmG zpMjr?<*R&+N0SFH*7q*v53Bw#)Y|l`SGc!N)>~1t>*K2iqkuL3WofI#3%w-W_qP@M z?LF2g_fx&8^0xim`o|Ai?tiA9~=zu(-m%y zG>=~ORG@rAj=-~rT+N#jnsog%Z{CUgBIO#EIw4$@f8#f;svEOURLtKd|D=k0yUG*o zt9^Alr{8H{v^KZU*8)gaAFMaG<91y(QGfN=$kMw-KrH&s@ z{I2)Cki^zySu!QTa=yFdsj_Dr4}Zi-U)KqiXLr-lQrCKYVejl1wVq~q-lS>lJ8R}m z4);C4=)C(-Uj$-(+3XRgQX|yyNH-Glpwap#29nMP>Yn#{F|93Z(Fcbmk8^h}e6;?)YP{cr9i8?W$CLzJPM^{_ zb~x2l*+AMV<2761NKKW>fnOPd2CKEps@E0n>G8g25HI8s-590aG^>8{jW~}%^`}QN zb3+fr=qAf+a`;bG7CvEE$=Q?o=APjBV*_lD%&jaGmpHH)OxUdV?a{}2bIZML)xCq? zwhl-o@6gE^jgseFtW>n;&*;|K1G7ESecbxXGP@=f)&|~+5T55V*MnEq^z5b=DQ^Np zExvJ{<$UcHVt&nP+QjFx6D{V6{l0v~C`DJ)!by{JvG4jI!OVbre3RJ+UA&8B2KNoV zJ{q?p;XsFQvUq;XUPYhHqr*W>9?5$uZy2U7I81wS@5IEy7aR)BoqGO-ZHN}vA4N) z=6v677nl3BR^;oDl$r17D({}lzkb|ami$3q{+6%0ZO>P2XTSTMA1~*u;JnEn zuWYH3OO@@;m@}|q-N`+g=N|`!=m_TQc5-|oe7pUpkkLCXSXZ%$dUQ){v-S8~kc z*4MRZ`@OpBZa(btYR(SmX&5^Cf$P?Xfxh5t@l)(05~iz7G?lyg;>w%nys>6g*Aun& z1R4ri8KzNtEhl%%MJ^YfS8#MamvEMMzENJ8om0%a4?9M!Q~hh6ukx*nGdbUQT=ITH zblMN4XLU!+ay}GZe>3@M*P2X=Uq4!(zdgE$E5koZg7aYYvHM$&7fEFtZsXl1C{At8 zT$djnceF*hX-fYSep|tS-KQ4k?h5}<>R;sl!dJVSH%c@5g_rpRNu#Wic^Q)@#T}Y5 zKW7g|>H1kqjqi!aoApPpyB<;R=$v{qL{-@5PQTqNPno;UBh4$LW(V*5Eg|#6`Osbm z)ilk@RgXj^m-m)T+fo!O!Sz{0Mtjk%E5rM0(hPn&etNib$HR1q%-1qb3!Y8CeY%&A z$9HbC#@3qjmoIH2*L7OT?V33f#y;mj?8Ek{cTe;TDk`1#_+Ge5wjr|f-T8={^P)fg zVx#F#N->DO^g6~mXvgB7zTek=QKAo2x33yGVK;F3i}0#vLnkXwW~^1|&pKYbL%#X4 zrt+WoyPA?(mEPZXzgT_EVMIaoys42Q`)AHWOR7HJoUPk@i5708w3z(}E!zHg`As#` z*xDr8;TE<)AEoS}-%TS*i*BvBQ62km<0f9Wf{6Ds<+4rLv;{UK`6p7F+`A6`_!d(a zJJtTG&&foE;mYJ-j;&u8@x9wTnD%?g#jfaZ**HFa{gA-p4 zJuZK@W4&V1#NTnD>Wbb=bZpgaFI5CMaXvfhzEMem=c&THEkXXLV_c`taC*aa_0+FE z>&952E^pr-uZ|^~?3?t~a^|*^UTK-7Wmg)#3;(=d+{CrpCg-qS{vy#L`z z>`v#L$_dsMlDgLqtrZu}8u18p{UCp? z>SFA*x$jCudRw-Bm8adT&A0d_tH8aeN$bE34_@W&@?sx9?ad3q1AM>Sl(i7AELt=( zRCVP3KHWXXf@f#`klJ>vq}@wlcGV6Z&5jI9gZ4F*)iE} zZ?;d$YkU+_T7Eh^jczGUF8$t^WXCR**ZkeMNW9)?^k-KT=Y8eYkLvP+{=)@Zt8}gx zufKhzy(NNY&sF2p?RzbFrTr{(QXkHH-E^Amd3)Y8_VqVaeHOjpekE32p}2Wy+DqA$ zO68x!r%da9d8&K?->Jn9-^f>Px?U!re|$-+{a#K*Q_60^0Atg|d6)Qmrv;w2UKz`I zvEy*|OF_9xKef#sjZ>WJ*GV-5N-nMzez0Zd`dhxPW((A!h05C(3@;dZ(__hX#D4a- zwZ76vNBM)l-#I$^UDGdPePP2w+g*1T`!@f6bn& z^!?H-1xtZBj#cXynZ$HINfzijJ@oNm-;^wtI*}pIUuKFb>ru^GkP1doAw`kIFEA4`FnA~cXma#qSQ}E;_DpvZ`On+&Zsrqzu}CT4J}8x zur@_=qs+=XAN^yVXxWtSi#L`ZT9$GALE*!9_OGUE1T3*CGLYT2KVbU$nUq%@ z8q@e2-sR`Gocca8XJra4BSjo>H z{APA`;^Ci{GYzcL*IRa+dA>-=YRjFQ2US0uEMCHEv$t=~-odSoUwN+FGtZ|6u6a^z z+;pA0zi0JH-(1rx+&^2AT|5i{C?YD3TR&gwCqCOiMs z=IcdP=4XHOOf79?n|a%jJEre&OZS>PcCHH_Ye%l=e*5-Ht*21Ew_MZmX}704&v+!I zr?61WNOZ1P%kFSWtP1D$r9uft*)dwSvkQ|bTatFHUvRh5Hr&?pWs^fo;>r1wtsl~^ zK6%PfxQ1Q0+gr=1aNFmk*-I{byyW}QP5ssp?ej8TEssyiep-9GVBc|lEx-MglBG&D*rbFRJ- zrm3_2imuauu+4o_qa|@v&tcom!FE*@HD=c?6m*3JdgYs|^7Up}Ob9En{#;oX^tnX%RP|}jV;4_G84ScSq zM?5zT_O=|ghIg|iQOeXM3+t%N0#i`T0vi{!3LA2kD&mUF^M< zB0gftK?-Dl4_f}J(Y9p$_F2srwaGrj8Qh5HKC9ddln7P|^`1^U42b`n9${o>Xo&=C zYihIN#NG{LX-}c&3HZ2DsuBD9UrqfEOkbo0)zZ2y)i0nciK^1$OZub7ChGRpUCP2l zh4Hj)1hwMh>Ui%o{RY?l_TfUYwvXz?5h|+QLA)5D!gPGfI_k?4y7*;Ehb zUZSc%$?@+vaoL9mc$uC8M~wqfAyd6AaSOULu$tdKvsNvYY_zP#Mff%`3o7SpzHyKM zaEed}4A;X-Gj?(!JpVD%!rwewrbV~FYLC$z9@0tfiipq2Qu$t5zmU(#3~nCdg4s~n z%oB46!^s!$TU^deohQutTKtnOr_5a|JCtUf7IFI~TX&u!D|TuP`!z8Z3ms;!+S+E9qv3`aeUme+R+PztP6q$@CB85fRDD_S)x z&a`$)$*zjUhc0vwNo5Hepu1j8dM!sLnFh<#-mVdP5JG1GX?bB0%sqAUu(N1g{%pdoQRSrfV?|{$BqA z-a&fk5p&ws8L9) zM879Jet)u~V1yJxTTw49?$%u|8*VPl^&xyomuJ9G@0G&W9hJ5w5Pj#~FUC9HNO|Ra zuR$5$XzunN@SO01QkE-l%PAexffl@kj%8Wh6TL&01<_s@KGf5C{RvZg&Fn?U#0aoR zB-|kiptJ(fK?|_pojD+$&4m|y+=rPf@?(RM54GjcdtC5R3(<2@7wy9RGg@$A1=)$V zx}@DQe<`xHKPl9s%%jIYq_%U5^?B&-o(hb7< z1G~{`+miT}{_ia>nSWQ-LS$7}Mf7aGlf_XhlWW1Ew%X?CqDT_{Kt)6&?SX`mqMM+& zAi^}3HrhN<03+DDbW@=UCECqXV2P31ryw~cBgg*>{Q2KoGXH<@hvPpl!~YEaaQlQE=bzo?US|9r zfA+?DykB;FZ(L^i&$eA>{n3R$`hy{mT+Fq-!~9zKFpMx0=7}^omN`X1vFm$qw*G7T zmc5|D5*Qw6x*2}nd_Ud(%zncm1aTp1-Ab=MKc88CSf`pBdR9!^ZeO*X%5*{!8kAiZ zSl{V#8*yCaYe)R(gG?0A+iWPsVheh-{4*9Xw0LsawM2)tuhR*$ZM zra1gPNC-Y&_^e^q^l!;Wqxwr2_124Mi)*jh>TQyOAdk<@2Kuaa6!`Kxf95xL;V zH_^V=Edl{uXEFymJ|Lq3+8EDAvsRn85xx`UN3h|0cSXO4(VEc!Y5$v`bq?$ZLAw3t zbLnaCdzSA=ciuLrrF&R5T-PMn@5GkVLy7G%+8=d#R%kXGi$~SC2$7=$tcO zbU64}O|GZ>qupJwC-gA-2%_NP)uD(1v7o8HU$#@mH9GYVE+1Onz{Y`KZaY6yN>#A? zJx3r`^;j9h^XvV^a2ae~VV^m_vF%kZ2q#RLapGR2A{9JrUB7%0*N3D}C}gN(n6Nbz ze6;SJ_0T;je5GqueI3;1>sKNL?!Gc)N<3-zzq+Hdy>JcTaDPA4UxP2C-_lxQXvDJm zZRpR=RYpi{HfCsn3N^PWyJ7zDvw=nNdt;*uU-bzF{oa=(SRXfMo`A^Pph@lAE5i=3=TF#g}DD#><*L)>_@} zNTg512rvJx{YD#TcLHc#FV&I%9d3E3ja3jP^ucu(mZR5Y4~!@iOJV%@Z$5lxJjwsM z(K3(-=E16t$Rq^fEqOevXCEXj*}53|EPuRVH5l}e5nHBh9c=8%>#}uqS<5;r8w?y+EPlEGY! zAB{-^=i~e5Ql!3?{qW&~w{hJXr!R=f5OE~cx3rHDJxPo!?|Ln>mgNX!9DV{h1u7%u z|I#FB9j-3u93^olf($sf1iNI@Sz#dEe5(I8U}m1*5)h+VqO=Uk|H|X&|2;ZBf2c6U z%R`0`SMb1+Fo!jpsYby3Hnq%k zUI2aF-{IffUFWDfoJ=tBkS^ZH;deNi>nTq8HZ@7MVYiZ1s?5i3N-ZrWmHxHc>j-E& z`gwRNNsPx9lS}V|(1>$tA}gjjHl0xY-F~a>zWKoeDapb3>}wvl7c?-xrW=11 z9*)ew%=K`Ls90=b$wk`sl4yOfzDk#6L)tnTRsfxDaBzJg1pS@*>aXeRm$tx+5Lkhi zNI#B$Tt7FqUT?|-9n*lav5g(w+Ec&&$OZ1&G=x%{`;U*{*15U<&&>Uwg^TL|puN0n zIpbiNrsw-q(h)BYX*O1ohyED&Q94MKk+ zr=3h*HHX|;VI3oXB=L~RKgY&dCPs9aG-HZ&loYME zexP2?!a_W#u0|;=Yx3o7-1=8Z(W1FoDx)o8g{sLC>GKAPl_6?2#st0QTxwf)!hfe` z+Q}K}NqXKP{w3tNK4v#?P%bchcDsdhit!;6#hHmUcAw~*H#k@OPZWZx z_H3x%uZXP;KU&3C7;riLKgA?3*Hb ze(@q32uI$+GfkjP!e&)_8$RZ_O0LP#j|^T zz4U6E^|5~Vy&fC{)RYXW@V&E%k!-<}GySwG>tXpDTgmJXHbA_DS&F|a5a@21*T>B! zN)Xp-nPLexWFCgA!dk~>iJCRA2oT)ZblKa+{inNM6|I{x*>FEOw$YOVs!(!p+iC|DD1TS$GUEz_2TK5koA|(`i z4mvC5eNv>TVIwHzeOfCxMXYL`*x#dWCaZ|+CSOR&h}N){1UOjA=-XS$jH-1|@F%V& z8{tVOy(Xcfe4MRPmbtAaZ^D{J(;L~NIMEXIUjQ?#Vf zz~V9CnA^qyu2ZI`Xci99nTa6H)uGu3%&)LsIO7&nDC5K(u0{r~9v(CKY{7_PTlGvL zt&)q`+BkN4$S7@+`Q`(I^B^Rip=~#t5GB&=NuQ@m!`bMyQEn#U3b;-p)?PDNcAuu! z@>^LgS2dVL6FZcf17U6ZLt3?Hh;ViKxc~0#q4%JfT(Vk5WkzOYa!%U4=EiBvU&bRQ zl|!{s`wn8>UP{jU68g)W;z1_D+xDFYjR}ZeQ3Zm=On+P+*HXY>SGvI=r9idizLCyO zW%{W0!rv$yLKTXp&Q)!`bMnSDAG%)C!E=@3-lzt}nbmU=-eB&xrkd0k`HB7WC)VuN zx~sjls}>YiY8Mf06we#ocRC~7qZJku7aZ66?2r*O@ook_?^FFK3@3hCHpai&%u}2P z1D$&(xvph;lYh2cM)FR=upws2q1rVZ1eNMPqhYbnQN|Ipr20|EvrXvkxGh{@j{C#l zpba?x3k+k>LkM$(bD@pq7rl*Z5M&xnhhj=GAs=!PyUrD7wA%7pyblUXy<ty%@^1peaA%x14+i5Q96dIQVwftA$evxiQCcA}BH2S<1eE@mfS zxhXujy3aF$^`G%z{B3<5tq;3Jk{$9?6Iq6K9mYQ8Ewz6~#9Op;BUU{S_}<2YqOLm~ zj@b;Oo6Y+NjT|bcteT|Rm{EjSWHQnGC#)y_8UOX@&_^&1$;PhOs*z2JZB(d5xjGqmQmtX(m+9U+Y$Cq&PYbFuvN29F6id~@P~OGwP1zDjCY7m-w^=Ns-AmLvK}hyZ zmSAAu6})V&sZi)3}6wMYbPWP%X$;NNuC zi=rd^Gfr~GGV$5BI6m-|BT)mbsSbZ)ZVAUW?SWABkIm&E&&0%V+36!v*;NzxuyFj! zwjVC))~)wG93{#bzXC@}7OSy;Kk+zc{ z)WW=rRShI&!A5D+ms)11;tpCgh47&M9f}996vjwmDB$o_gGiL4Yn-PHVca`0il&qK zeJ%{n7ny^s9;&ur?5UBIdK@mFdhjO5yIaA|@YXliSC{i+@{{Lqa!j#Ce_^-P8Ko;s zNCh?hW8oc!+8JgaXEU)>0s4;AzV5m{#Tk8oKy~xX93nJ6gr348hlc@ zmO)P3=pp`3jdSdDHmcCYJN~gLgFjcgBDTPUB=pZ!B1~bQJ!&hgq%bJiG~zoK*$Of; zM9-f?nxtvqnY=_ThaHJLH-cQn)^Os=rN_P6h+hi6Nt9Mhyl+>3#-*f*HoRftB zm8a1yD&Fk(x1&kVGW0dQ6BC4vRJ|9N%%95=EY>m-#=A%uuem|E1RP4pYaNi7q%-pY zB|J=O$7+Pf)ppWY(fC2h8=v3f0(}(w7^^h;lSru}#~6$99<+)y*GTphibXeHS{uLc zH5^n4NvRk$4&qVp=14gBfly0qR!MP%3X+k+%d6oCq&j5E88;ZgrkDb(Z_ z%b^RO(aiCEy>1STc`RSq-eek_JjAL#HI!S0(dpEYt1wF;sjR41iU?5(O{K;TnnwSP z^Bc^k6O-i8QCW@L(LA(}vVw1g7pb7LC`Y5^b7XK2T%XEGkd1Ai+T+HJkzbx{GRgHr zf%D&bz$y$=(4IHLkWNnR859qNs0FLdg%JjT}V5<`4UCkLhjH-a04;l<*1N zP{<1Um|pZ65(<87rx4^$(&#W%XXhxiCZBk1YFI|RoPNsBPIAX=P>exh8E%nYZj{ z1|P}Us6T-8ZM2Ljg9v6+Ff{mUOB{X*TzuWfC=X=^|Cq1*U`(*q|9HVD)=S+@AC{VQ zqM=dXg1hestBkY5Mns&(4qL=H9@z29!BK7sSFMq5P@?CnA`@sROhx%bWeJ&uR&fx^ zxCOXD)gG3kqV}x}U{Y1iG|166zrp;Y`)KAkLBF7a6JrbcnuJ=;S8u(?OZ~e155X7+ z=)E4qzfsz?Fd^E+JUVhN9)S-V04K1DvSK^5E(XQb(pIE6rcOF+E$5OE&q*E8V0XbG z3l*J!8B4{B2rNczh})vhjEZqo+1+7_9mM4kNp?6!Jb1I*{K&k+{UZg%`-2IRE{vY5 zqie4?j-dh$ z7a;+LP*&P}y5lr%Q|qTu z%VTd!?~6z}m%7f)?)YvcmWLeECi{)in<t z;47`LKc~~PGG|$EDfOY0yZfzJkEi5JWwGIJbcd7NQhU5vA5*q@&k_@cZHlr@ZSAou z$lx?Jo)c?K&4WVqNUD5$?Z%zkE&HbRb~w*p*Wy-};c|Vmvf3&;}XPMt#5*wrrb`Vx2e#jO9Ndj`e(i0G_=!F( z#OM-!U(6vc$}a?lq{fq$l4E-RZMNu=C*Jpfv#^nplarBQKL0ln#UZS?W5K#mp)nYI z#)^!MMbmDw5HM}L0MCG?$OeaPr=V$UoP@B~5Uo}6c?IDQU{qix6kTcyIsT%Yqp{f9 zrMz&=u3fyO)XpRKMsI}9RC`r7!sfpi5$ta3d#zHzZGY8SAi}*As4JX6F4478|FYAb zufm#NmerA7{wqfCj6>r%Z_6dzFN;j!w_U7NXjau)<25ZISwTtuP1Q^*s7^TG7wK0i zM^!H@Ils;KR&@-kDE$iJrB`Dj)5rsL-HgU1FEN#MI)W14sU)o1OI z5uuAK=}h#$knCI}>xE<{LX6i&1J;Mt5Vb_0rkb-u&!=Y%#3w=nQ#eNn2Q$~G3OG>z`04uOkTzd43MR>m0qOA^Y3Y@N|ZL@#Qc& z@Hp0}G53i4w@MitL7yzKM{x7Tj86wkHB{vv1d9!ZIIN;o6$HLdi1F@0AvT@is!OSwJ5MUwmhU7S5<=r3*cOfO?aJZ#Ylpgc^qkqBB?#ByC(|f=WsQ9x3~l!ODAuC zeK%-!=vxx`JG}m)eR92MWAwUvVa%_7CPotw+Qy9~S_;N|`Z{-u^J$tLkX|wFuBz~j zw^4W^TUZwAeV>W2_f`xHbafTX97%-c-1Bub|4NK;6eYmkC|+N2k1G%D5N^X*L9fY| z^-zm2pU=|XkAeLgwO4CGMG;QQ-b76JwJDA(sny_MApUP#Ci%suE?T33%Fo_5cZ>*s z(&rQB!Y7=-WScJ{LtcsC=`p$ZfEoirnByW=B2J==_42ncJ0%*1JEBc|K&_FmU}yZj zA)Uz{o!UL7c$^~}N7{HpO)>V-0gDUj&ai4*0lL|FgG%i;5kVv;Mnww#`4Reg0oUD`-pqZaYQ=!9yL%un(SDRy%(|5yj zGJK|;mJ`AWAI8s}uyeQUI(ZrQ=&R|{wOSW=ynd(MYyYzShP2uu;OWAZGVsigd-et> z-kNn-EFVxv)r(NBXVSr`P?j0Hy!E>7iES-^Xl-S_7B>M^tPZ#_55FQZRD!Xx3%DF< z&+R~J_)GG8WVUc%ACPSytg4ISF=?TL!(r$UzS2+kT?0>M(L7dxqX%G}QlQ&tGC2yr zOn2O_&w-tcm>i#*`-&t-i)Lh~``I7rJHHJ)$C}iftm=xS6sb0wR5$@GGRZSJLn6W8 zXr5>asc?X2aI@M=Hj{oXga9d8Fo+6QFiqpz$6=kMxIe#3cJu{Uq_KX@aDyhHX1hxIQJ-&Dwbtm!4dYeoIeb*=ZX-ZQL4uUl)3N zt~q4)ovk7)NnMjg`0d7^!EG(MM6<$T?XdmqLW%t3aCGq4jy?s83mQG0lJh6rwwE3kFdFJ3y?+-5h4?oJ zVfm##Ccrf_~^_>7F8SnImey42CkLUA(y$KuPrHJsz9$ir}V17pX zmq!;GnN5Vc?J0PQQ6+xN^fJ=M(Hk2BAs$?lH=vm;%bgmj2qqD%>{j zknK9jp`7T4sWNRJ-2Go;mHApI;r$E=Y;F;Fo#1SVoHvRi(Ti9AZ1GtDCKH;Ak~Iaz z53m#?EQ(4xYH_j+VXrg5`{Td=6m+O8_IvC@sX=Tu`F(dUhLrx3LLORgzNjb~Y&Oa+ zHy+xI8NvnlU>gdxGDEw!DP_Kr03I30nEe!*B}EAo!{ts5A9WnHKNPC1#a`k9;x}Xn zZ4a0mQexL;JND$d-qChsmJB!hTj*1(j5b6z2irq|Zmk}A*;?#uQGQ{eXwNZ_shkSs z2&I?T9yqrqe8vVF^sHEM#B{fA;~GU6ifs}8y`mQ4xf>ZIglBSvl9Mc>Jd`cvd33a- z?vCDWg}c7NYP6YapBHEUTEy4bY86{ZIX&6_G3bxi;5G6;m!DKSOIxBG*?{_o^F_YE zq38+IpE%P;VbK7)^G*CYh!hiKivw&?Hf$$<3~$rQpd)g}fPo}vhNgXS=AHwO*pFsH z>|I8}^zuPmpE1sN@67G*f~rM#a^)6I9E#Hf*AcfDbwrm~x7ckC&4yoxg#k!KM%?h- zLew7?YJ>3_PqquhH0X$i8AadmqQMYX>HXc9msR&st1z=#1XZq5!wDwtuo(5M8fPRZ zyRj<}-3Yl+E8-bKV$>n#_2_vmuXaHU=irP21nW2bo2XhaJ@tgn^~(Iv{|1L%kB895 zhp4DDrb48lYlau-oVQ){#^9P7dT}kA8b$R3DYijU3J8t$wH`%S2OWdhm7@8lP%hcE z3=5y#O*(YGAevr$M|~wN>oFT+A1$=qZS4&a|6ogIbY- zim0#9TCIGo`XTtNX}|e@MZy1{)bsy#K(KKCcXR6h90fD~XW9L~BoI9?dgz*)jD8C0 znzsl$^YWZ*vZ71G*$8a9bW%-6leEF4!M_fpQPRtqZDJRUwhNgh;&4r4nI-V_f@Lw$ z3R6ZVu;VCGxWb*MS)$@CP{+#AU%1^nfn1p%0eil;Uo&6+dv1?)KdNO4xjuh?%{}I* zLJ-FyFAhiqH$!xIzZvVDdqVTG!K-Lupkt+y1Qv&XF&Z1{DsiyrF6|YBd=ViJE=5mX zMTN00eghsPxD0d!TO53l^SI$i{z=yVNPk^rrtw=EXvZqyU&$WJFHy;j;PnI~BwFx_ zz#fHmu3k_>YZr98seFghxMusThJ7Oxs9}j%LuKP#;`*R9g$up?cH%3+K~<}B%|~L0 z__{l-U?sB94Oa~P(uJlG%v@A4Jo_{~AVQYmia_Qxx7it5>UqZL3p+v*4VY@~tcZgo z;yreJgIOdkZEK!A4ivUMcrW&wdcuiYB9i(3bPoOGL1FoeQi0b$*CrsyIm`QHS)5Gv z!0oYtFaNsuVYo^%tSOsSEMHG2313LW716ce3brOC#S=^~(f7^-B@OEey+VR%4!|xJ z_gIch{EKqXiQSM)*$wF|HEVx}uVe;o{tRzplBhROUJM(aR3B@GLjFwe>ymEyK8&nMkM~1p9V873s`-vm6$}S1I{^LP@%`vq^Wy5#j3y=kg;D4}E^l6D0 z`4)+{^jVbZYXCd|zyQ2IJ1=klJ@g|m%Ak1 z7ikQX-2b@>Bu(Jt3PkUs=_jw@BX2HH;1ANjxL5EXfcAY~#dHRgNuzm?yV;d@ygSIL zuODkv7w$LS8u9(MdB6O8?y#BVZ~J8hW0y~csOxY2Gtj4>!_S93Dcw!U0MuL*G1T8F zR$559zv{tzqNIjxg@<>wmHA#ngprAmB-E|oabrdcysZG6@diy+zP@2ODAWLiAbf4B zaw%*TP0A3+$&vTnj=mt;Tt#2b^hx6sb8FKUc!CTb}F$te0> zq#L@<$Y4ah9a8g1TaJt{M3NN>o6{AUaj5CuB~%Xr;mBrGBLPQWox8ESy1BUBYWU7r zGy6*?qN{fSZXiGg){FUw{aY3!3NX-_g^jqKTQR_17#;?BFi{Ko2q+_>*oLXP*hSlWw z#Um4XZ;hA_x7wA(D9LoS;BJ;R9dl&Z1rfku$Ed6ax)#6oV6{-9gmir zZ6_ckx%+GTA=0U`CoOkWR>%|rOoq70W7_TKIYH;2iS z-FmK8R;h{ME}@Ovi}-DF)Ke@;=dl`Eo2GjXzLlymqidt(c-08*E2$2xhzd5QkDHrm z9q!CG)V8&}HoJy$PE&C=TDA^Hw5a@e60avGXI#ngtmf(}Rb>DZFKpw^D<P`t0QG{sI^{{1Q9apRa;N2ZR;vHg9dF*$dm z6raoOla4L5b!E5C+}xE#itmD#tlqEX-aFF}A}$B#CX|+=%WRl6_Ev3ISL>cs%})Ie z;`YCMFIj7ZjuD^kEly}?((FLB&g<0+haUE9iy&|~>yRk()Ipj*OWW`GoRu{%IVY`W zC#XHYyzN^$)Pz;iT8bZ_U7i9~{+KZnIpve9i9b1goCp<(9k-}+uyu&q%plAQX8%e( zRcfn(t*o2W+0YW#nW%J^^oK}?!>Fasfp~cqa$sidaLtr=s4$zh!?328sy`kY&B{fD zYM$2{WUyYia+9UtAY;bU8%YU~>Z677(9%^P;T}#_b%mWNP%n6T6jYwLT8L`uIPsrc z6dB~tJ$L^uv0>v>rk+e*%h-|}FvOVjMt=f6Z~3qkGw@-BvmO_7!;OemBSwvITxA8mb5JBn1=}*)7Fx|Nc`2Y+AA<$Eubi(3tN4DN`5fBUO2LTiT5VwOaUWc z5*+>2T2XIEe6_bl@3((vbYEX0??9llDk0PA11pA!E#Ne^7&+ihx9FE_q<0$fpYL={ zn_fpYKv&=Lw(#Emnn82xseAJjPz-;$AI|X~KGmtMRMYJ8+ncZhh=dy*k!CqI5_~Y> z&~|u2am~=(ZRd7^Lf;NNIY}jew{Wp(s@fbn&^keZ)AArmC8;1!y3!g)q^UsnI2H+b zM8Oh?2`xe;5nivm9hQrz>Snq%5#zAc^zK50jfw>NB!^{Dn|#Pgr5& zP*p=p2KOe+JBZ|AdP#h2Q5~|$Os3wIx;kptHkl>A$SUnaDW9I~hVuk_6;a?4DQr{K z5}Xvgs}?n#@hqB#ZhdieOr%hb786A2ia+Xxrx1r64bVsK)ttRwTu z|1bE^%d~g$$9U3i5E^G$uL(j$|AR^_+3SRO5#yx7-;BVP@AOT&?#x)}qB)WnqoGiZ z`rf!22U`P{zhRxJ2i}p`Q#mu1MGY^94JEV1A_6;)kgC3j&U!UCQfWmov7GPSgMqlR zrjy@FQQiyx&dpvd!zynL?n@nIg`Usmi%9CCTPM$1nnblqPtAcpm-4Oy97O(n%lkz2m}&Xj>s*sPQckJ!cDI^b^f zcJW3l)leEmH5K(+$$Rp=u!6A9>vUfJp>kw(B#4lTe-h5h!6Az1Hu5^ zN9-V;dK)v$Q0yR$`co9$A$oAG@Ggb=Qy)D5Jq)kVNgw^25_V1OppyEN7kXf0F7FJTMKo#8pD{QFHNeUe?dJv#|jvVHp>=ZK? zpzI}&{v176Rah^HZh#WDQ+U@%eT5p9E@oUteT5u`C1%`3ZHE?iCT<)%|`}%DQ=ug%|{PwD{dS|U5y#0URbY!zA1Jft*pfWJ0*4iqpU>>n-DXI zs;u=37Eb&?Sy_u1HX(A*PdS4Q7Aa;BUpa#wmQ}n!9o-^QB!*fJEv%xDNgSOrW{_Mt zgBo_GkVzOlORPW{9apTt0DUw@B$s+QdXP)G93`xwP>CMaRIES-omSi!NUat*D5Xq| z6{ez0jS^;}OpO|bQplu-9v(Spq&$ulW~V%k3Xx827A+D^4UY~{MqL~wQb}DLDbh$y z9u+K#jw((fjD9FSzySND?;6PlW*OF8uT8R)QJom&JVQn`%pPYKYm2Q-#2H|wZ*nc= zYi~i%%Ftk8Hh$hF!MY?F$evXZiO0?2O3si#hnJ}xzQ-`M6`Hr$o}4t|EKXL2W$cTx zs}Wg-b=U^yEKA~naroKZoz&sXP1bbODB;0kC+VaG-7YE9PF7BYj0*jta!B(}sZ;hs zLDC3*-d?6psZ;!d2U-=Wgv=R@zsv=GNfW_0 z*l&RXx9~+GYJa(l7odXbd*osSP$2(Fpkz;(NBn}k^{6K?(=Iq5O zpog+g)S`k6qspf61%%8NjeSvb>f$4?RcTYs8m;7v+P?VdR|x{}PeJpaMIISNRUKJt zgpw7YhO&KaAYmz6#G;){6ZK5-vWzukNd&cg*|LZ=Zb=2OR4Gf&8nq+}m_;L>zbsafqykpr zBXdNvqFhbNe5PMCKv`|$fnK?#69s2oT?@K@wJz`lR~El3#%72p=o333a% z3&;U!_t^`-)(zqWID*83#RK9&<3V@;bzq2KhyX-TL=Ya3>#TbchyH+mfqvVdo*+&3 z5fa}ZL%q+&`gm0-?YRt5In#fCwzQoHmRXY(7H&5*Q`~)6y5#8>@$EX~p<(IQI3Z99h>)``&na>}lfX z#k=^s;JJQu-BYr7uU8kQ=X0;W5FTD0(p964=-@+{?@?R#y-l6H!AH;fmw}@X;a^1Bsw<;5N2JMG+`k55X6dqtzEQEnvg&e|)7mvn zCMG(%y3TT!)tNOltjg0r|A;4nq-d_p+k+*t~7?$h;C^yh(K0SrNVK|WFLxc6E6A^N@h%Ys~knt~KTEI|T6 z{NP{t_u2Nz`XhpnKyJYTptvBoV7!p#A-u5e5ck3N?fd`7H3da_W&4xUV&eMbc3uTu0whe)+z!YE#L=hwnlo09{;1}dCa6VWq5HIo=yECv;P(sLQz%=AEcr&O4hz`gSh$=u8 zBn6NHf(Dogf(fD&BFhITAz>qxgDr!O0&GA`0V_ewL9{{?M(FvVOsGnT)DS?BXn=SS zO3*3X&XvA0#FON=#@3^(2Y#Gdl3rccA+3 zzl93CHWiWL2$MglBJz64M`th4SPtjN*FRVNHHK*QrO}LTFZnSK^91OOFX4hl`l#V# z{N4-TVto)Uf5Gjme^GEme<2GDt4qW6E!hq;;Qs*QAEg(!>8*I7>`VOV=9GD0Fx-hL zmhVySS;N6fj-ik`B_opR8ew;q?fB0%(OyUG03L}SI{#Eu(d z1YQtT|AM?cCdY<1BmOw=*9;;r>Ka5Oo=`w>4%3YPtV9zsd;~J)vnn=F9G`CHOi+ zZVLMf@a7eP>rhZajuZVu0~TzB76oaQ1*@e6+T{>`tJLRBNp!$HrEcthD?!19@sRx! zZPAM*d|B>yDL}kg>t71~#uJ7sT;pknDimD#5+{k<-4om+;C^51IqGx&;k`NWhPYXc z~}aGqdz=&l0ezhi3)w$4%C zAvX_5n$nQ$6BjU4 zF82~~Hpnc@soky?sf1risg$+p@=1PArc`5n{0u`)=!#{7&x;T*9Zm34Hq+cx_7JoRHH=>7$uOHyHh}n^yPlJ(@|GVV!}SR?N`M=FBo=x@9I}%DZ^%p$h=Jur%7Y8YZR?Nw$g9 zH6vzk_XAdoksKVuYZ#d&Nn^-(Q$4#tu>7hzFH5YoXl1@j8ZXwyry4k>@RLTIbX#{H zR4g4DvnIMcl5<^e(L`(L+c|({%2m*-udaggeE{(5X>7; z+3SS@b)U}txPz5p%I|&5uN9fPuA85U2vI~0T)H80hCh{7IS%n8T$D`G_u>=Bj33YBy`-cA)9LU=(NK2)3w?y@WIF{A#?MF)}ua!GWI7@3RBJ zOM7NBoP2h=kJY+J9!Ibm=jDmc3H%WaR7J)oK<1YM!YR~@5Vrb@fhD6WGc_^--#!NR zmE@lcC*dpwJ3g)BupT$F8l}v*cw@uy!-SsAOg-R+>o={@mAX=&t}kKbG-ZoUB7-&Z zk<=3_E-7iXu|cfxE!bvhV|w1+RN$N;_0H=CnrSOKrX9Zimz?Y7tzxPptwjT+t^7sk>fqKhUtCzL;Ku z1km3ILN+=XlaCnEN!d2pVe&c4y-h?z4&$@QpxN<7I zCtgO`V^1gUrdPtrBd&Nitk!?aHI`*=*oJV%S??~eF!fsN#yHy90n>hPh+=SAYbl?j z;O5d|1MX#XPg)0(ex#jIY#1fI!jSmbqMzRC04pO+^(xlH)XX9>MM(eywZnJE5p6dj~6??MeoFQSp zzqM3NKBGB3-1cQHeQ#J|d@%=iy8B}RDj3Xc65f@ z+1)w4?_F34O5+oj7PZQU1?y#PnG#sjVp7k8h6+Rzb^q8|wg=~Pzj{_M_^JxJ1!?$d z=}Q#wsmVz#I=qQS4a0~!=9M)P>0PY+NiOC-R#B7fYo1GwQo^^K7SpqXKf14FNUvm` zi~}Gmx0_)Tbz(!mP#V^RJrP_8hg}pZNFlLKN9I+#OR|1xOwgV*{<21-B%oksT{>`M zs24QhG&k{W>)};CbA!d0{wsxHYDn;ue!2G`TYB9YOvShXv6lKQcVgQ=x_2UI9)F}^ z5|zWG+d4G&`9FG6n$NLpTWVK!4^M(ZR!^OfeQO|}h-6nvh|JA)-ppED?S#Uw2& z3HNYp6w6$Yz4$fi-R<);1f%NN!RO6I7b>k=h2?am&v84z)U(F(#7uVh6ZqXwl*Y7| zG)W)u@DIjSp&5bRfmg(*pAehbqTDJyuZSI{+5Ex8YJKh((OV3#Md7an=03 z?UgQsv8oZsy>419)x&$eyp~dl<$x(cL4f$*6z%srw8<{5;m#>fU-tf8=H=jM@BX&6 zxXQ^uHeh1rboc5*kv+XKNZHUrj`AF~+-x2OBab)W;xqm4YhU%$Lm|supT>gXo*Iv| z2J|^W=+NMtv`Gfx-3ABXL;28wsglNaNXa$A&D7=$cRhGFEtzGq z6lu=8+Bs3}gktZ;(ymg9Fzrtwn-zJKE^WSivxpk@ay+)l6b60_g=VpK_58*_d|tP+ zic^lpVK=!>z<_W7z*nvDcouXbIj-2DRAgs6oF&#wj|_VavKVEwWg??w^5Kn@U@bFP z_o_GWY+~L=z5=Zjaa>k1cPxCQ%Xobj5+Gu{t>yx@}5GlD%5BH2(wu6 z`Wlw(=wrv)8_Mlb(4h)^&%-kYlV+7SA?uZ>Qyf=&xN7~)6p{`3{vOZ$T7;PaY7Hjs zMfQ*uq#-!J$78{T%dhlTw?mC|RB7^FpBfnx<=%}C9F>=VFt?sSq22vv?EEV@osdU?&(!^v%=n(rI#~fYh zFe}BXt0LSqfhSU9|Q+3FCHUE*MeY z9q_Ostco9-WAM!?2sFVer`y=_k&mYcJQY2Elkow~H|Rb3Sm+>T4fj*cJ`wJO7qmaZ z46^h)6pcOxUv6>*ESd_jJt=I`A^=?q0t~ zw=$sly_ij(-XNatg18MoyEC4TlLGnW@hAyrAFkOE22(cPbd6w41Kon!jI0R6RIk^p^$rruMdlzp6lysQeSHnnH$&Rdde!VpRISr zU;9Lffn$v(e403NAnKx0EbIbr@U_oVN8~Y$g?An>LEh_z(Y7C%YD4b5DIDoz9?1xd z^Qz3_UMbHAx#E25QcMZI-q4hg6lucXjzx>-3m6?jX=SxBEW%owj;>1m`u51ir8u2V zPik`cg3yJFyg$}bDYCEEaNkeh^Iq#|H5GKklQ^?6H<(Fe-ioHLP!znHRIqjGYc4w? zYP0jKN#dp7_yjv%p@%m!vrm)q<&}}BOS~P@PAjWh56Y+)ykCwLpP$JI0=`L37W~7{ zE#Iwe7;lN1MM7AJEaP&6kk`%&`+IBgY_Vz#mG?A8U$$k4n-hXd>x>V=`ePKFg6co!Ya|Un*G+g15t6B5aQ>l@daFIn(Oy}HrT1lg z_G`1&Abeg0hl5aWlQ>=te_eHAg~G${=eEQVfg8Dx_bXkFUMZYkE3MFnan_n|?yq>T zK;OmcOgQi5X{l3|AiT#`51iEOIByM!oUPv)w>)!0#~n-maXE3PESgo@8BoAI6}yi zZbx#&>4A7jq5hz1jHZaqZ7udw?@;dJVCac4HJRKt6Vr{Cd7xVjRUns)U;ZoW0(e1m_D>C&K%ELl>%UZWhwJ$R; zzfx^GnoX@Mjdf2ronGH6-fjv>eNyjgi67&vk*SiEanV`i^P|sOEfJZ#ro6-+w*1~! zcYAVsJ`c(=KTgdqKcn~B3|l?EB7A<$CSd#hrJip&Pkz>jm-Zjod(G6aHYbYE=n@e5lK-eUUuR@u|+fnl7P6S6snl%=e4XvCbM)|J3v}o}z zr@oRa{Oz)ow$rPLC}>1o2Og`jvO`LCb}Rf`;n$Uum|OhzB$?)#N}N$&zd!b@*1#V1 zGYgAUctW+jj6anqp8xpn1tJ&03c6&Gce7Xch3WbtcxmUT`S-r(`BbPW_w(RI@|VK% z{6mO17ei~3YrkNK6-F4Jd5_EZv|b?JpU8!>TE4WDym?Pk(JsE*;h~2^Z)C^F#j5N4 z(5p-dH({pF)1^d+;}oO%uPoAvz018A7bRq+8YR>ziYphNp>$BzP#;|WHMD;)1~a3L zPn0$MLKL4GVP#QVBrEN8=W`o3CUSk$TKD0Mehsgp^?5g`9_={lI{TA4x~W&2 zr9_tK^ydUmYBB2#4fqW!ZvH zi}C@!5xHxg|LwKVQ$?#v>zqK&H%yjv@>6x^gEjHDvH5VqE3_%OZ+=NimLwS)C>#!f z@(kx^k2BdUNOatKM{#*az++HaQigS>ZF_W#JTRJ>XnLOS>wruDB;R^`Opff6);r2X zoBT#i3qO_Z$6UKf5=bagsZIH1uj1me$WlwTu-rpT5FOHVi@tTSz&`2kraI)-T*~+O zpou3&5s@_2qQG^0?h=pejR$K33fc*=tQuSMH_GzffBcXbV!-&7K(&+jdoN{?dSIn( zx01C&>!9fjoPKU6W=<+OujayTU%<{w5-PgYg`PbtRKBt z84iT5drn_J{yBD!f_!ib@oM`gGb^QL_Y$4l=Y$^JV)Nqe#)qQ*`UR6ORTu6K z9q2R7$-LrAK7aM<1tLBUp&fP48!fFFmBmI)DjYfn;#+A#T5imZ+lu*HehXC+jo-M{ z_|@zf%~M-GnUi;2`4UCid1X$%^9gBbx3|_6RU+8q5~XS{i;jZxq$X^!LaiU7(tjKh zHLgCftSsd37Id1>6X{J%5ElzzIBJhAXtbGJ&J-txKCqUMJx{;AV3&HpHPf4wCK1Z^ zl`^<>ATjNXZ>nR|=+=)DobG1$xetos!fSd~5Nr6n|9KKI^XF_dTbn$PUd(L zZ0h-RJP*mZT7BaJYFlw-o&Ewj`iX`fZtck44oI}XSEm~{IaXG4;}|liC3sDztwuEP z&IMe$(V^~I{^fml_WtDDxDvwTop_~Rn?#3(Q-TeSyEx;pDYYz@D@&B_@O|IQ&-4+| z&Sw)-g}n*UW__>yJ`mJk5X*9v=Gc_6>E}w7vKhL(7pedBA->kO#Y{)dmHpqJTwd^6{E`lO7Y*wz7luz1SH~ z(~;`QLY@63n#^0V_mqddge(0><_ zLH9QJh~gScA0!(@=Pn4RxIVFKiN5JGnHZJ3aB?8x6OS<}bqkkGP|HSc){=ScntA(4 zvavaTA3Y(1wy0-g(~ps%UjIvk^t-AV!mO`q#IC=zI%>xri(xkge$pe^4kr9W>FL4+ z!j9`b-waMdn(l2+oM5}c-$4^TST!-XbY7a&m>ISaTK3=3Z5XG$a>>;)Nq`iN_32=TZ8>{{lKaoN$io-M+i5$tC$qsiv_-Nizu!} z(Zdrxx6_s4f#(+pj9q+Jvs|-Ni>bsI7R9k>tLWDp(%a%9t~~uzM_~xF{-I=4A8W<&)%C>2Gg+`)v;0;(>b)+Q=3-zO2<{gE=?}>*!vimfK zhCUkl%_%^&-C*ivyn^3ur_NL1EWgS^ek?W@g8FF%BJg(&(nMy?9C1e&%>NVdamK#BVOJ8 z{)mmL2;Q&zn6Tf09dhE@=V>MW{WbaVj_sh<{S{uG2Ntg3?Mi7kI!{Bm%p^xbVvZ?o z%b!Nsp0lv5%9@D)Yk;FH$p>>$Au=-YBT`Ig4B^w#^-2r&b1KoCDv9MpWOQKp*_Ymce zABLNabx)PK94bj3w}y_`JZzNEQGFN_Ns^CgdY`IT)~q$KP#XAS92dkJyoBg;EFFRC zs+O&%MfDd{drn-Rk{u6e9_jIL@TKWp{>J_!BRoyN*4kcwfqKz=?!c=pD}*C_OUbzM3%eUA`+WFhqwEa>e-aS-_aP6&?dg(eC2#w$Lwr23OnMu0Kw(;cjJ6p z46J%q;Ulv;odr@dsU9-&xZ4aASunwOc1qOx7(Ct&r`t1H$N6jUM1!}9-0)^+;!c{b zxu`TG31pmb)@Fw`APzr>+?u{pecNsLV(bM1;-PTS^3n3poS4@U^w;0*chu$OJu)ND zzi`5=BK0F5-kbF#Q{C#zs~JP8R`Nrcg3o8d1g87~ zeViy`Yhj?cMQ~fRp6=4elEEpKa!HAt4i%_^y9{xpi`Pr{(5q&ci$N>Sc1e4 zQ=gd{nr{CPed9yd>iV6jfH0%zBS~$MHL=!xi79-KDk^tjJU1H335 zF$LuEwCkKVEG^#6@8!gk@P|a~7axAIn4%Etp>;w~mv1b**>?_M6w5O5U96S$U1XH; z4mJ?8P{U($s~w$UH@*Iz>5+02e;=fl2(A+;%%?Gwpg=V+t|eaBkm~aueY50|e}r zS~qdtsZZU1(?&>ADp&CFh&s*0TfS`=`@!V{`TD7aryEa+g!Ve)B;KdJ;afNg>`Q4; z>`jtP!#;fMv!0`*d%x(kOvOxqN$Xx>4Yhhlu{j%^{?z`@iDRsvL=rC-7dfU+Pj>Uk z)xKt$%<*k77xZ&RzS?>{$!~h$XS`xgzhFx6+;!7p1qntWHupZqL-&cTJn8Fe4=Oh0 zoiV4c_601ZY!y%tCgp7;wK>03YwRkFSGb;_W-8H2oFu)FJBTl!p+p}@q-5u-boqp$ zy6+;pIW$R1*SkIV+Jc*nkJ;YP znV$PxD){Y*&mZ$$S@bSDYRHx*5X(q888u4F1Fzm2)f!+n!PTxxC@Ph-TciK#?aRr?BI*~0+e+4yaz z_W`~vnG^mcTTlGbH?Eb~d2g$?b~fleCt2&cTD2zaG@2V6qVUw5(c-x?P6?ynqmq&9 z%}P#um%8p;Vs0ewE;AL#EaL4+V-GjsxAhWMxWUSr#k?zTwN-QInjmPz*(ItEyu4q1 zesh{y?`UH(?Ne*^`*y33c7YD>7bVOH7iqukeT~kq%9<2dzHqB`&By+_Pao!nY9i|? zYs{rJ8SeH|Zuek6O35L2YjRpgLu~QIbIVqqA3i9^jqF7*iq7#Hvy*)Dm?#cVOf2yGG;4FQyOz$^Xq$vm6(H# zi*y2!rew8t&$An0HbizJvAyea?AQl03B1WQcN9#QQlTL(xlQCL4dqJqJMmC&ek170 z$(OcU&u2q06-%*QXO`DiV|j_UonF0xtcl=%)HM7M_4(<%!H`ZSsV`2NXQqksP(lfL zmiHt-ewkw7Ue?1z{F=8pmu`oVJ$^wW*e0)^yuJk;9LLF=xq2ZH@8hjBeu+oaVtrHP zhOIVO7w$(Tbgq*Umbp@?J?pJ*o_qdTTesfLeQkg!me<#2=ckL??tnrEl-bZ#p6Edd zt+rM^z9Q|HuhHGRx9{nj5)#F}I#{+S;;-p(*yy-o{B5Hddy&DUabduyZQaYGp*-)PgQ+#K54qtzI=Pp>F4;-*5lTW*X@M5jw=4{Gv#Fz3^%&fYMk5y zbl#<|e|ELh&=eTw&iR#9uaZ;e5ctSQXBCe7zleK#{{8N# zl^so*pz`B(ynzw>PEoO^qZiK`RH&&mvPr)1Y(C2SFn&R`V3q7~|NHC^V;)6FXIRZ4 zfr2NV^NU;z>UZVL!$L{P3Vh?E6TX<)ry|EIdZy|TW)!tkzB7EI>ih3TZ(DTm92-V= zIlnXa#tTgS3Jo~_e8x+X;rU7v>jv2rHU14xfr3d2xqvxi{cHmt$%+^u`gSXRaY5Se zLuqZ>MR@zJ(6PqlkmoKB>7U4SRqvKPR$Ha}{PXR!p-FV)TMJWn67vvhvOOyL&x(yh zi*)HiE^Cb|09-ASdAd0a;H;e*SoXZ;Vb1g04SE!_`E!laBi`8RTXS3Ds8dE$<^% z+U5}Pdg~J^FUoe0QGBPvw~U0YiOHYlfG?Y$iYhCxHLqySX*^q4BNG`KgFjYtaFpK` zwcwb)ia)IGH!9VA&x}O*d@e=C_Y*HAi`2w5AI4S_0y3LJHKmBJX{}K{;;!|O|i6Gko@CXQd<@C z=ABUvcf-l1E}qFfz3+)f)Z}s3j(4gI51)SzJ1&0zjCMnzH>b93gNyU1BQD)&zrPB5 zdDGzmeNRA{u*3ek>FC0};-~tCiBx8BoVVs)k`DukE{EooGqaP#i8~MlRS=XNrYg@pCD>}9q^7oNHoZ(t zT6ZRuJk}&iY2qiUp3+tA|JZhIjN4}}Tvnz)bUdza?8MPZL(Q`&us1q*_D25P-dbZv zUG90fZ#pqE1HK_Ev!0(M_rbD~ z5(7iwATyC^Z_=lymaNV zXY^QA#u5IKlD_S525#fy;qoT<`5u-uzL8N0t!!^$o58x3NKzR$>~_L*x6HXsrj5}L zM%LfvpPkOZFLZg;j1)Vn*c)nHvV3rb-&EDu*EsfFAMmQ8{h9@RqnUG>M^!lnEg?sV zd4ppHxR3MKbqM?6R>E1_*0>+_vpjaW=p#xr z7yhY(cG#PCr~PRHWtfzZCaz5|R`t40+pUue6mhs;=Xe7x9dEVd%zLXI2L+ghV_v>s zeKe(!?K7=%_~;c^MqA!TKT$S8d}S}u55AuEfi>*eiJ!e-Y9=ps8!O&YYiV|KjV9bK zuhSp6J&^h8spIB@k3(7Bb{|#>qKw#tu8(C@JC6p1Gu~w2^R_t*{@R~j9#M3Vii@CH zjP*!oa`DBjEib|}p0%AWA+CM&03hjVzT05u{_g1979oBnTRub7y zA5WR|<#W~exO0rJ z=QKobTd_usttJCD*5{~j<*o3DVuQxsYgyno5tx&`9pvnmDj0I+nk)9&GOMO_80MXR zJ`wfW*uWVdbn_e?bt+Ns&#HQw`?D~@?I5Yz#pfg#W>fW_$zK-aOFD1aJ+=DG% zyYo`cy3gWYzJIjHJD+wnsd4Jj=48`T2^q~CI<>vSssU(Nn~FqCzm*W)K%ih9h0>YY zn&|TK7hxA(S=OrBv)LcSN4GZXzI~IS9KFgmLPq~&h%_nn5`9843A?lBy{|Ljs^nU; zOM+^SpSag!5*OUfopsF_XX4A{V3d6A_g;m$+~PtyBqu~lC3)!>2a`SY_%(Y4>r+_@r;oRclo|b&C&6o7bN8WIi2V zzU&xq{f=|Bms)N9XWfKN6`zISywm&dH-~AwH^N35=5ECbyPdf|vDEB+6E9^xv|896 zA^X@d*dUC!TK0lXa`0wUi~ndLmY01@B>!iFS*$77gC%X!(f6NZKVs%5Jb0$%F>GU9SkbazpJl&n9AXM6p2~b zPWJNXMI5#felZm;^ zP>~Ev&UkXmK;u#lQ7nz5?wj}051lMDai*7CIV?#OT{xq#X4JlX-Ar({3)9}B39k}f zFRyV>H5nkNe10x{hn?$KD)& zVbI&UmaBGGqj+wno{{|^sK)~1X#=KDKE|!ZAx@%j8BENKGlmnpOH0gI=>@UF0WXil z5WKa`Gf~C3QRE0bHTOohwz7oU`hw8F{XL3@{}Pxqw~-#~YF z23GnQisF7y716`Qy!5+sHbh37=pHs$z1F>K4r5LxSd(AqBA&HS>PdncSY)1)nivUg z*0gZ(A&gCsSz&l>SQH*3d3brrHuBzKU58=7-V^@H=azOZ@&mM1qi*wevm2bJALRr_ zv4c6l=lR{Au0M zh|5_r?T4e2@U8r{0o7=}?6j(xgCOBz7Iuza3g~ujuDZBh28|%(bKP3c3YK{_oV%lt zpxRm=YsK`C)Q7P&LC(j}C*4O=W-o`jGFStPb+p0ykvt3$A~J&kIP#z z?OKRVea;k8S4xk05{l}m!x&?#PrT^+$O&%q?F6Y zphV46#gMtS>CW^|5wRzA6f(!g(`Yp)wd^H>_5QkL^jr_jHJPMyrI;4aR; zd>eYxjeuZ5`|Z~Gt?>ODMf#2Ad3TjmKfU>>Q!x@+E+|VJo#^JuVXyFvqrU{Z%edam zS6A9OsU`Z@Q5pENJbtF;=X;_@v{$74>FOo#(FwQ`+7~pdDZIw#cqW~tBY@-Z#iLeE z!CB)ve z_*I;hW_qS$O;a4!!NOJ|Gn(2Mj#id7UmkW_7FzLf>rjvv)#L!Aa9$iIGZO_D15 zt`O$1%E@n3@p@P@O7>YoUy?Y{V@SiCyE>C`y$DYu&7u!W?6G6?+lcI{lNG*jP*{Ie%Eq$ z!xQy3W2g9}w#e;eNwVkUXR8?Pvzkfc-wYb6d-w&-Jllt}46Tlavy>4ZQ_r#HhIu9U ziDFxu6j(Dz(KdVHnK|?iRWC0ffepbuo)U^7)*LJ0QO*?vmXP$% z@fUZ4GDO;F3f^*PNI#7?$Lh!Eo{E{STfi95Im&|P#ARKQ{_%`nm75*&xm4_zqZZ#| zRoTNm?6Y=t1=Ch8PR7$jsq7s}*AnqAYKyuQ`3pvT6nGOXHiY`$FugGh@ViD{u!K|3 z8QvnCFz^<1pqjn$!Z?^AVind%Tg$ah5SqqRL{WP|h1uar+K(5;Z^SSs-t{ZL@K5%+ zRO{GzVFG*mjF3R1ZKUbv59M9?pooY0|3i=2l;~ zB}s;5dEOs5!%%t3rSQ+*Lm>30_Yi3NI9o#a0Ka2 zNl8&lPnJvC)zs1AuBofNmb;~+xvc{f%p+%d*Ve%Y!v2qB2s#}CSl>F|EFF7N@)4G0WK*zS~)?) z#0dB_Ev;?c++BfQk^-8w1o}nY)xy%%*3lZmu4n-SXzT6+T-5S#c6PA5iwu|_=_H>X z&|3n)0T&R27(<}QQy4!#@>CEwg^Hj~g@IFH5fKPNP!Q+>;DCxigkcEa69y3$6asR? z5y&h;LMRgu9w5N4(L#g(TS!<40_6urLIf}bgy0Y%K`2lT3K4=qfds%10S+j?035iA ztO)@_)&$fi3>5}y5P*olfJTH65GWK1TomF55=4M}z^Ed7>5usY3iy7Z`CxSw%-%ptm(#oy@f?-62-Cjux(#ZcZMq=9UmMpj#aYfG{m= z&E3%!>YDjoQ)g7+KgNMTObqfrj)RVj*58K!Vqs|oRHSO^4BiT;;p6!=WIRBbKXRaM zBfuA+1Qc|}+{wby&Dqr461a1$EeXWW9o{`4if~j z^YaS`Tt`_#poIV}1ZcrQ%L=qCKuZ9$U?>X?S_shM2Q3&sDh&!+aCDj_svOK5OoO2; zIG7VA4Av}g;4E5!H9sa zLwXGbJp-Iaje|Lu(-ia!>=z-hU*KRZLg-q+G&s7?EWn7&P=k*iWndvf&DMX+F>?=B zS6~G|O=;B3L(V8$N6UZAdS@qRAOo-81Gs~14q4Qe+sQ-JG&{J;T}LzU$h2FeQou!^+d5CqVTNHj&jkmqoS z0O&gant+EudB9mgBy=N0fX)LBq<6>|kw|O|geHQ_2LuM31MvW{qt5>cgraVr-)|@+ z$NBwzQUFbW2_Rwi|0IS2U58=-e_-gZl^l&YXp8~Zbpa4n1VKCy09R{4aFyo=Q3Z{Y z00g6O1jHBwdd&xO3V?MAqU%JX1Bg@zFii+d0{{zE3y9JJXlw%T0Kgaoh&V!^p9l~& z1wj-8pc_>V#83brk(LmM*$6bIfrujjrU`;+0w60uqaOnFObGN$0F8GbHVJ^O3xcil zgXPdX003Q7dtgogx=|L0y#iqCf~eMEXr>`32p}%l3KWb3jmE!l6zmOvbRcU2oJ7SB zjs+T<5g=9yffy?QT7sYjMWZU%`%o|qfOZr%qj?FMv!Iy>*f%gVM*_J33>;Aba72Hx z8?a6Qu#ujjS;{XKhMqxaJ_C--FSdaiQMfSD7b`P>uIK0%s7K1O8%6;0%I-JqQGb%*hW%3qx}cG`m6930eZ6h2}xPS;sqCe4vzj3y|@r3`FstF>w z$zQ3OAo#5Orw3!fKmTamA3ptas-~%+rKzm+|C_1_0JIAV;4A>u|81&o>3L|+Qz-^E$1Rz%e zKyD-<0{D^;z;4h)3yvf>06jrc6cGX7VICkkLI8~t1o+r5mW3>ZK(-|UkT9eRfNBEJ z7l7jlqIjMlstqJV0vHVfkSS1~fI0yO2)Hp&2I&Iu{0|3c5AqNMLO_0s2t!fV1p&L`9-0G0R7?@g+fO4 zPgMxiwElep{8Gvi2FGS@x67xHx|4zMr zCnLX8sNad$UkDrs0%+>-J4yQsi2)(+*JJwcP>F^$5Vn6OX@8-5zfq{)DckSV>vvlA z7pnIgDg2$T{!UVUCvbluQ(z3B$OGd?k_H$*z&Vfr_)ka*K+upR4Fuia3Dxfe?=Q6F zcdGDbqVg9y0I&%ZSc6pWck1;!iGlqAu}C`b8!7yqr~nENvQA(~kWm46jA!2kPDj}QP9{QuxUZv*@%S^rfY zpbDV(0U-Skn)~0#1CS8Z)&;UI;2fpz{Iy=-I>0bMpOEJ$pa=5OayK$`GhZIrfy zjs-{u6qeue17zk`y-4-tkF;Mt0D25Sdj7bMw2=hrSNi|-3FQ5UKge?=6GG+(&VOs` zpOcZl38a8l_Qw?cMMe-X;s3LGj z%Asok^#$-* z877E+as~lV7=&j~Ux5L#4yqgoT_PZ?34%}YBA_p5Y9fLr2O#8$pr5Ki&qTmF(TWio zH%e(hBKM#Ru01+4|3$q#zRNf;bkw2mhNj;#<#SB23U z7`k7;_Q2g5s1RD`LhBM>IZ*L~nSmA@r4hi)&@&5F3lvRD0AUE|YbYRjAV(8a3}C=i zM2#&VGC<4q0utXpY zioS1wu0vU1PC#fwS?HcX^(V0J1J;6`gJ49Ut^_j!%b^t?U@{=v6GFuR>=}U;x&`!n z0cQ_da{^T~V4DDyQvmEwVXy^IqlBTAUZfWH-y@Pj|8|?{??m#iOy)l(k|_4{S0ahR ztKS}{0kr-D!N6~h04f2Jc>!O=097lL-hi?}S_{}nMhv8DqPzoyAe2V+8+ZG=M5eE9 zW@l;c{wJkI@vbSb&CaK1YvFDK?4kga5&d-$VL^aBIypGGY9V*yApo!Rv^BTXl$Qp! z-fZ37G%Q_ZobEb1IU>0xuoUoa09 z5&E;};GMDR?~`Gv(6?&$!eM~{dB(w2XqVHTeWdVXd|;btSU2}2vDTT{`-t~_{EJV+95Z(2SM-=9 zEw*LO#15hca)95vF~1k;L%c|(9ff^VGWhtc`;AJe%u`+eQ@2Bt-Fufaoz2ZHK0Vi8 zjhQ~E<9KGLQ@39eMH2@G1^AUXp0&GW0x7Bt^J;7G*rv zdfDgX>?T4c?}}%1{?-|lvkdR)PxdNCn$O4!lkk$(2aVo;IkV5MU;O42?b!H1JEEy* zi&s*)D)3xTeBO94=iq0mIo)Ie1@SH{eRlq}uYTM?k=0YwB0B}WrEG;7iH$VpN;o6S z_n&3gm-rkt-Qw&qH&*pef;8NiN@if0vrEu1yPsPjJ81P| z|3cVU%jKZ7aS9xQpo2B#?+X)Bh4RX9h9k(@aNUehX4;f@*Y}nHhwn{`mx#sP`<|S# zmOgxb*x#b<8SCWVbu?=1>$3KvI5u!YLdCR(N@$PKuhYcq13uGRXyO7^UU?3g?*cgn zj-*RI&I^f;QIRC+)Ehfv0da3~%Pw{-+ zT~&H-V3Y}D@2}(@M`A_$&)w^Z9+fAov?rR4T7s&tiJaYfrrpTyMdWb_G1}eY@3VFO z{g|}K+}T98K_`vpKn&Fl4Vf|nFRx0yoFKB&tB>1fdlN1jdghooHQ9IhU4MDJbw+XW z^KkyXk;(vPm2cQYJvK@Fd;5ZwgyRy#lB`cQw^`ach9H;!w5wKH+qc&gpGUZiE4$-q z}P6l*RdUjph>2cv=HJA?GIh!H%@hXekI`X$k*xqH!H z3K`r-r=eYi_1zCM)w`ctD=*EO7^|Anq*^+ykh7DPLf@9(={0woV0uRcJ7B0M>}?Li z3M$FD^-$2U{;a>nWG5=Hq}=G5=ZCTW^b>+_9<(D7?|o(5$Bc=yJYvgc2BUkYK2FQx zuSlmg&RZXb^kJ?r?>P8hu&#n_OB=M#38{f3xez+b{^GtGx zlw`O{QcU2%#I=@f)oB||^|*ekkfO?~2d42bAK;x9ZOwEv=a>>Z%#V{IwJ)@C;SWoS zJg6A?LRX~WTtxAR9Z!k-Dv{)3`F&XkOBg3<0)Ka(w#qYD$nm|QAy%AE>^@ny!(O_2 z=^Yvr%={{UXhVl2V&eIE5_dISlS|y+r=^eMtr!i8yi!3ho5KIm+>UrK zNrG=;m3D1kdB>Tr^mR$H(RORW?TqD%lg^8KviFwgzhpW1lJpO2-Q2&y9a8wisoO`p zD8l7inyL(=wVSn`6&03BcO5x`X-Y;Q{OxSD4Cz&pR>RbwadvAps{321%fL@}MBYps zBrynMQq0k?4${ut@)1}OOURkesMoK?!G~9Mm*m}%v=U-t)D4d>D~X%Q@Fm78y3Jep zImiLS3im!F!@tE3qHikMaczS>v5e{+c8E?c##889%ttJQmAG*I&ez5_dYMWk#fSSF z6DeXJ-ZXCw$JE^6)y*z>& z($qJ&U$S~Vi-A826o}1G=D-VXWo)oAaGAVZ<;hZ^&%0CP@Fi)=KhXE=vHOwWba}o$ zp2}D4yM-!YZ5e_D35*HV<9Tl%nOpPTJAcH`L@qcNS%`>rlsnyDYzedE#SnpSddr5G*w?xbd-61H zDrYi@VJi`s`*C%?7*tt{3Qi?qvrWP%SG;O#!8vm0Te|aP+4@&(+Yu!t=2tFS?#pto zY?bTpHq@pMYmLU@-D9%JfJD{ZdeN6Mf#_?;9!*8q`{c-XcDd{=batM1o<4Exy2x-% zi<2xOb|D{L#liFf&q3b%%#k!(IfX%UNTt0eI?#rY6w~LsdUICv8x{reMyw!HExgzI zq4)y)8gE2gOYJ*8$6&rOq>$!cgw<+5`$^bpidL7G{oiwpq+Hj_dWp%E5*8M1KNfHDfSiNIVhMQepv3@MVKCgRxUoi7{qfpqlF`_XYN z1N27)?q-QP8mk|&5}C3PhLIdMg7sQ#-u0;K)VAg2X>*2?*JL`Kt$!lsd$JUclLNsL zxjU?Mo^J3gI)%dIkXFQ*hpG(2XMRbUm~2uce0qB5xYvvI^oUK-U(+vo$xBL^44U)V zF5#o|Wc1Xcc>enAVw%jwH{CfLyBHZ5tkWgH&$1+XseM=Vl9#B@J8jRdcAUTyETNDR zn;?}pa56o>S-TJ`p*AaL9ar+mxvt_MgsV35gt2AoevVhkUW^1!%Yu8rkW^6%1D^47 z>YOfl_vza0BMF+b6}@z!sce|faZ@Z5-wmqDtAjfVZ#NAB4bHYxmQ0QU+^6M|`W&P$WzJAh>IDCMB{y20kS3T_ zLT$!v!t$=?PF>(PHVHd*2_8%_&0=~RtX?H04f5_&`v+%>ffc?R9Oi4sgKtw>c*9_y zl*}7n&fv?eogJ;?un~Tp5znyUsv4(_$8g};mEiY&H}|+@KdDWGf#ziFfq+uUu<|U< zOT9!Y?sun*VQ<*G)MhE9BF)kiCQLb26X4?OMW@A_y^7HSl%!!7QiwzC^}cs&c(2bz zN6_CEo+Y_H>oPo1(OsQ$k1YMA*aJzNoT#Yz-m_AZ)2-2w7Imj4`OBoi2@idD@+qeP~~lDeA6B%KRNqt!U6fY$-M3>jTFnld-Se-K$KdX$zM zL(oXRgVF7$Mpv5X6c5FODf?ZAKg1{~P}I$fCQ0eJ=DPKE(|zhZhMGe4o@E8~>9)_t zAZ+nTcxajk@l-t@Zd@wJ8yDmy-GJEuEo zyYtqpL3^rJg{5i0&u8Sbh*kg4ZX%(3VKRNNm}Ij3rDuz;{N$@9V@08+d`xJqeNqXh z##%N0xF4cPw7$xFy}os?>7lxx>Aaat)Jw+R>DLRF{p|#zno@PRj`)P*{MtSQp5(ox z6FUjRUJGov_Wf&-au`{=#pYQ09xirJNKq7CnYcg0k!0O;*(yWhn~`+(OFbWC%ylW> zB<}L@mr^ai`$|(>sHk}~V;Nvp+{RSRPuWdXYij2jOr%rK8eGu^}y@|jO(_aF&c9U)s!GbO!0@|^uFKU+@KnaUA@TB54_sc zt=aT&)ZxZAZg!WAtS8M0MUG!Ocx10C4xNSTrBh{+?d&{t;>WI*6vL1FM4iZ|qtKaZBjDuhA4?K4bcq7Ejo2@tJ-`%&5;1$b`yC&!YRVm{ah^vu< znDxCEy62?6bFx@)&9m(wcOZk|0+H~TKscTiCRd!KZ1~$(>6eq(?3GraF1Qg zS=F|E?j31Fde<}Jv9${9lZy(NVdP_Es;zJP9ir~!q$Q*o>80JjqllvsmErv%(YPU2 zw*o`6cU4O#o@H)MG}`mvOuTqK9nQqSK^q)IxpOPgYT%AlnA4$7pU(&kVqn(tlZS*< zwwL9Is`x>)9bxzd3Z<7p-#IYM2oMk1Rt|UkodP_LNB8V#A6+Pp0@3+iQ1-{1Fqh>pDK(NS8xn zyum$I)AlkK(N7=uX527sw{^Z=>C98*<=!mP)u7-wob_TPY`X&rZ z)_KWDBjpO`W9nA-2X0~V#Q`@QZ)z;anp)u;2|qR@=YJi~k*Yt!_?)=q$hg)1Hsw)h zH^-Im{xRc^UqZ<6GNMW^2UmxB>pj4x(71W2M^Nvk5j^9}ER&T;=VcxJ_=Sr%Iq)(> zgW&=lpQ_jL$9Y3{`8vas3U2-wFd5p)WKh4osZ|zk@bE%qCl5^Q`28#0sl$aLf~zpW z)D)>@c04*lh2}SSq(=FdYXsOc56WiF*E*biZ7C7DQ`J|g7$gZ%H6uy5Z&5ZaP$h8W z%M@%Qdw!(?quO@UQWgL8LDOIp7Pb9walPw}ot+B1lT+g7A0$g(E@D-mKfZzyA6Yac znfqp$!Fo*M{ntPaS0mvkt8lpLL}v{7;=R5$QgRx@0xY)((?yfb=YmA-T1`0^F$te* zr;5dE79UoqwwlqtLcB=Zj!wL+ks$i+lIo>I@*j;xPwqyJCrS4a{j?RTLaa3wVch&c zVy$c1`R0>ZLWpxpA-fnRgpz%j{9c5=81Pb@eCkE~iYrZPjUIJ&SeE;zCq2CW+FR#Z{C!^BE#xRg}eRe)sdk)3{2|_4>TuOq(|5 zgYKF7<(|Tl5z=e7;dv2s1%jz`am5f=Ytt2%iAjLmNY38mw#nys@(LUCD<$3CBGsT| zqJ+^UsiYS+b{E1A#j&JhIk&j|Rn!vK3&`6}h$9{A=}a*s(|7K4l=X7mCQBhm9L2If zr{zXc8r<{1um}sAtb;XL@xCT|2NR>a!hQGJUfFQ}@{z35S52>XmZuSGO>uoR6?G)+ z%d(7>c*$6H9bvxMdA4`>Kczr|1l|maJY%vNn=S%hM#@9c{$+b?bvjU^ro ze=enhO*7*a^vIrZncVgs{m5J`{+@0n2_xtNX>TpvMu&vm?E`zbXiwDn);-;Ra^f}r z_f^i@xaXG>*k43?W!?x%e3J2Hvvy0ez@fUv=X-TZ5}&XH4Yxtv``21J*aRm+fsF@W z_BeLRpyTx_1eY{w@@nL)Bi=bymysDHspO9ywvFYPoQ1PpUKyr(CUX3>x9@h$1$C0E z0$o*7{N=ZgSb_curlcaWf@w)OSxFL&tD1K{^e;xL4aEb^qzK z?dg2toug0}vIs%prO3_Y+ofE351d;2tE#Q)#cfG6z6P8=J@g6~Y&^Ps8raYTY8d z{{9u^`+KU=H*D+^JPD{FTvLejC5l>%u|c^Sz_n)k<6S9*mxQ%%g9z0{%^Pd&l%CNS%ZYFA^qBQ&en0w2x zs@Aq`bkbcCf^<7!(jd|;-7Vd%q|zYW2uxBCq&p>*29Yi)DFNvQ>G}quK5ISiTJQ1g z{bz4~aLkEwj&YAG&ilOT#&>a8a!BHd1U8p{wM`ET&lnOSGZmlzYc(8uLf)w6>&Sg9 z-J!bWmDG7F8|!7C3(s7US-!5-HQ`Q56u(LTo{o?q;64DN= z?X=R~@CmcdHF-J|H>wx!HIV?y5oo)1e5aOSwgDj@auD_sNp`V}OV%Ze23DOa{$uC| z4cbF9;_X10_+%(7#b=ZOnwa;YoHf;S)tROjn07UIrswWx{#RDj0gi!a5*WRr*e_5K z0y26C97;U5Vmvz*m{mv3UwjZoQv-JG+4F{G>se2}HXPNh-s5kSy}E09PD``hI`fVE zGU3m??b<%Iv+S6ta;ZW5<83Lj%)sz6-}s$@KP=c+h=DPMitj%5eWlvk{7Qj?`tT^J zkX349)yI8{<9_Q8RYjt=D5x6v(;v5a1y8Qpk;)RUCQzSp>;}>kW>n7eqKdj;O7(U< zFP9Wz8-^a_2kXk>=R0a)CAh*E#k`O|NIE8N*$J>$!#^QTW7AZmBQ)GJ4P$xpdw(MDVT1xLHra(Xgo?-kThBnro@?_cM=Arv#yT7aRX3{)W$MtteH@P_eb(QI;0JpT<2 zdJcmzM0Kfm{@JW6v7Zs8->IAqp7Dk@pF?+9;ly<`&pwf#bHh*{X$HfU`qM|T0@hen z8%#_-W!QuaHFFT`&Kgu?8jUg;vLyZIT(wmk?vv$ULQIf-LXMR)iB3%i_Y73mL)Ei? zH`e1(1L@L;t@WHaBC@U1vHPZiX@byulv1w+;+(8>U9Z+E%h4-wT3_G~t3h<4L_>I9 zjWSrvPo6K<5;r%+hW7?mipY_+(}y!?79Qu}zUdM==w7Bz6YhPoG786+&bO>;?a>Sa z<2+z)(4W6w%*fl^Bb_VpMTaY6jW028X_z)`0AQzZ1HRG`0lU@Db1cOrk@N>`$GXz*=wcwEo zCX@T#-ruacQe12(BagAwD5;K6;e$zRgD++W9>^S4g=hEJ&h)<&=bnSnB77z6)E4xG zPxWDaMd)d+PCJHT>e!VGSxt7oxpV(+r{u%LckE{NMGq0)l||Q-UfQj%(+?;wywj&e ze*Y96S--+UZhYi;(5#j8>4$GrWTc50l9O;JjK$i^JU%XVF9N=0Dh_4CPc6+x#^zXMa44nx{k`C%uK?%S2UDa~~$ zJrWG+cwrqlem#Zp$f6QGX=uS=Dlv4DoAZrY_j(%{Id00w)>huc6_tWZbv7;NUi38RX+|V1z|`8&TY8^$<9&7Z zoZ%w&O;$}}fFgSv$L6l2MeT-6?h-m>Wo@@|xisIyTZD0(?)vO8Nu={wtqK`}4EI5@ zf+dRfOi`o<^yd6#X6SNzcY9CCsvT!}DP1m@+*Y$p)PVd5T8|y_aIs^Ym{&WzcBjSb zB&T*}?Bm(E>ykhFqteKPFgSG4a7P4@*D-Lw39fdFPlkuvto(zJm-U6c@Url;3`Kl- zYhV!1orX6Jo5c+yT)1Zm=AE#X`K}4FKt|fQ^3OkXLA;l#LF(m{6OKzJAe*L-E}rQg z)|1g=o>?)6Dx@~#@+A?d!fj0=eEg}xA?)`azp0b{Oh{3`@l;6gRYu0)-X~RTtxfu; zj?=T>#Y=J&uEHplIM^+N5vd`?spfR$iVI%B&Gx7?Q(R~f&tM-bYH@maSq;uY3aEu! zi}k1BsOIlYMzM|7(+Y`iq1-%C0~a`XPg`z}^wP03re2);nYD8cNj944pm&D9H~zB0 ztFQQ^D@Vg$7Ec_n}>ROn>GO5AXYk9J(o z{6a(lpSjIq2W&O;N}$(3;v1{D61 zOBn174iaYu+XxJ?)`)#U{Hu(DU|d2u(xA!~r>YMUV=pHkT@ciFzdzOGu^8;|oOs{< z*rF$iT}nMJUqVLdA&bVnSD><#gH+LY3Z>rhrxy>`xDCVfJzdL#FBB)Jk$yM!UZQAKL>tSKY|eUOAe142y~;@c%Bt(=KEP8ja9PbuQCNXCfE0~pHq>iA=gEp;qv zf|DwYxuKzMP-CiB1Z1_JFwt9iAY@5m=qkqT?d@2y>L&=uN_4)l?o289MA+dnUDLG; zZ6y5O0^0hIYluHPBe_;4AR>-XB+;5@TN`E$hdN(q>F<$q9cy`4YJbGH$r2G?TYqO9 z`c&V>#bKR#!mF@+yj@bKCf_L_Ihj0UO!Bd**S?|xDAm0TE&az6Q|xLv7wv_*EWC!- zH>+#`p6gVwle?3xC(pZUM&+v`ppAt{sERiRfnu1sldmfFCh0pW^r|vl+f>nUyU|x8 z7|;!CcJ}yQ+?xuvY4H4F82vrCg~sn3ILPl{p-TV5`DQx*w=kC7muHEZUguX{gMzIs zlwnCP8YOL6gySbc1J9>qtf-ReQ6iA{FmrdSSuixwEsI1*-oGTa{JOhcU;1DRm}_YCqp!$EA$duM1}Ls7_Oq$StOc= z;69ANk=uR{eQgwP*r4Z87`czx82ubM=CNwg88Rt<(sJu$Q>2Xx;;0-qEnB#_=cR-H zb5By~;z$Sh4nviJSvA{-$XX=wTg7Bo^os$E);rN^QW94>t#eJtW_3QAl(azOcbtSf!x__<@#x`@ygpRzu8@={1&=7r zbE>>#=Rw36@a(TdyM}30f1lZ?xe%CvijWvPKfm()LtH%6q7+_SZUp-NwD!6F@rlL# z9$M1*g*Ykp!D`VZHToyY^TQXHstGr%c_T-gq>HoMyiR$3_f}h(tD4kbt&K)iQ1`xX znx!Wj0Kiv6ESBGqCXfw#qG6H2XW|L_yL6%)NjYJfixT3GYw1YWTb$2A6(X!i+Ib!a zKOFC7n=jNfIQ5G`6G|X+mfCpQ!%-U({vg2pLT^~HObvG+{rPq@nru9|aYsp8ih8f$ z=?m@pk&A|k2iOHhN|s>c&s=(HuIpA;EIu*krq6Mo9jYPEDc5tm8LD3P79q>i@-QE=B4HnM_EeaRSx%&LM?o05Zh0`$j)yn zrk}2y%!-p5?d_2nW})I1qF5VT>95nWWQbvEa9ZTAzz4nh#I%1*J4oz)&IZ?f<<+p> zWO}HugMx~*^&HE?kL0)xUZyFAcHIqmtpB)ThcM2)L)(ahR*FLA;m3oBcUjS`cC}7b z1?~QU_|!}3XDUC+3@jzz^A}&ig;*+1$ww(%Pxv6wr+?nm271kVZ&vw!O(h@}hj&M;^7TsrAvzSw+c#5PIgXq1~ao`V0jrRPDW4tc+)K zog?3o7@~@q$WF4w4Ye*Ksu1y}KGD*06(W(UJ-);~sVb`KkH(^x@{-AE9VhqJx%tw3 zl6n)(j4sk`3m23WBlDoE9qw`_4qeIa0@awpCGvG(gjWb$G6gJi&nKoA&cSQEDT6|c z_5%{`Yp+`0At`i+1qDj>NM*^@*cUauLrxq+)-d}@wZdI4JsS7S?7*5k9AgXVLLIQ8;@>ecR+rw1{L#0Af3?{$vIj3Rn6 z8TvAP)jtbXszD8lcfIg;pSF|xz6zmx((P+Ra`tqQ?#;UCB9%dr^rh4}5z5{Jg3jbm ztIdGZ*vKizSCwd`@jr+$GF~Ni_!=^5p7Lnq{YthGp&Z@3H3!BKYmlt-(HP&rMFdSI z0-s{-4V$smL6(f1em&Xp(}C2`C&HfxTX34~=n0N%w7eZD=GFpUoH8g&pyZ_vsJI-&w2Ntem*nMkuGMQXOzQd@9E% zt~M=sfM!BgS-bH|_~|T>`Fb8B!#128xb^5{x9+l@@z!!kRYi zk(E>~HD5Ipx(upk%_bMxtJ!b3RdY0}IM02y!m$!QlOsdn1k*`s4|L{cbLZE)@RBhsgS{KfYK=L8b@cd?FyurEAy z$=jqI!~vqrc@ES&z0c9mM$Sw==V~22YQ8QHvgp^8&-YU+g6rQbojE(NUE^v-E67k| z^(%m`!((TYE);KPtgJVzu$N&oJjLt7;NJDz*0E`B4Du-a?sY-rbE);U^7Zm^Mkx6W z-pRZoo-k|tEF_v3pT$%x<1BtR`%P_oisTpk66@Yxo5UOEE`v0AfR$3f%YY6DGmpy$ zGMjUEm2p~Ba^T;1pXnU50|%WJTcrsVvOjNl8JNeaG<@DAWb?=lH6IzCK``r`pr|yjE9|nFT?ax*PB%@70eiH;*Y$ z{e89h)j)KZMiAZ}mC7ECseFttrjl#&{;J_QJ7((=X_*dBdYuM~PFrO_6^OIi&K5r+iLF~v- zs>^aViANTB!!ymn^VImVTGS{BHE_7hGrV~HV#vc~`QUwHUi2&Dl#S=!jYq{!qfA&T zE`|dRqgZ@u0+SiMLv;&5D>~OoSNn?YHybQrU8Dv6{sl}@c~tRU8j}?cH`AL>SUy@_ zPT#MRw>2VPU<*nc6*lOvG)%up0>Td-#E76G% zGhG)Nva-(fE8B&G^rN@#GV6i#_tQNC)QYSl^9u45U*6{%taf<0IvY1%SGV84%e7k{ zS7+&-==N%$Z%P#VA(72vdAAh}UK~{04REh7OVuNDLUk%+hgN&Aw1u0%N5@tgaiUR< z=g+Y-Z0qnkO(E~&9vB^2SqA0}WX^J6yN|P+nbV1q*oEweqW?iBje*FkpLF=q{`PX8cb{CV1ebmHq~fGaxa=7B)x)flk5RYpCiVy z-t0!OG-n=d7RA}|J>H_VAFPT-d&Cbjw`wCmIZfCeWaXTB+}`^X>zSm(9G*P9@t3YC z_;`AOrafrZX?JjfW|?q7zOS^`M>|Q!uG#h7XSUai*4$Is*4o7VbGT8ExAty7y`HTG4$S4jX>jm)b|t{oe4ei=N}bA^S`zu zf1~8=)k)btf?kg*d}_FQD9_gxl2P~&e^h73TGuf!nzVSEq?c}5d2{62g6uxo8IAO) zRZ!SBb-Upa%f@5>^qL(H?9MiR(tDjb^rYh+BdT66+SNp90@wjpvw;bYzWf%5!5D1QI zz^Ak7>=Xe_afk%ttRQ-+v_~7>#wwnunE7f!7~dpZO4<4JmjWU!y@uv5E5RwR;FQ# znhYZ>|h`YBbwmC}!cWTJkIy4 z!P?NySfWuK`#P^cPQkU?`C*oK(Tz%+qtGsQ&`~jby3_S*Kk9B_VlH9%Z0h~{1!K%^ zs1p4P_Pv8g-;B*HbVB!N9?bQNKPP4!L1uBd7&zHdOfg|FqY=JZ7 zet%QR$m;HNO$y*L@M|a~J!c zV83JoWPs^ujXy;mhz7SH+SQbxa7Ux4 z)k-L-mJ#^=LOoagI4{u&so+zXWsBD9Rc34|TSgRo`VboHb zPvXl=k2fFBB`?Adb_kaaR}XOsxM#pVB$@-?Q~AttPDT|M<&y-`>iou^B~8EdJjwM* z?+kYc$Z?KzzZdSro@vZVh#r)6YKT58FJfSq;Al29@d`Mcy*#7LM84roI_CM)2Rn1K zZgxdi7hgZ{4L2vDY4!Beyl=3N#yaQytnv)&oMDA?(@?wy^2q;0)ZBQGE|mbhF_J0jWo;c+4-I(h9N z-~qSY>PrUyBLlQSGccdw2-L&YrN#qRmd&ciNjpqhwSj(Qdbcd$_dVMY|4CF>umAi% z!~e1-A+eO$Uz+UwcR`W==VGvLdsSYvWP?v8H*8PfZ)LPvi5Hjate9OpKltZkV#I%u zlLPJT(&>(?ptvFi>89Xd`#n^_@SIB`D;ZwfJ1b%WM1Ls-n9*fqdz!{?!dsbHD}7ck2T2^RmxngQF`>oz(#s5Cqn?RpDw^OU^7W&B69l z4v2BNx@@?>4@;Y_7y)_aq|bI1(4SWK~BPf8KF#aH(FzfKJ}(D|>=tRtd)n z@ELUAOVfvrI#{u}&^wvlJo;bM8=d&eq=I}N{6)Qh8$<(c-~rK}-ZqHIr9nqp`H3*( zuyMJmUH&;>!s#-n`oMwx&Qbp+xfJ$_v1_mG+37t%_;7$Waye<8@egl(x?L!I712vT zCglKt6omwKw^<9uCRbkB`o234`IMCnzHi_STy>`$B@!`jwce>aHxBQL^VHdsPE0{t#!MW(kyV!)r4qig0aMY#V|@cnUP52jMHouFH(T ziBo^~q6w)#7x(>z+K$u0%Dhz`p&%(;KWWt{00`a?kdyp4qF5;(-!=G+NkQq+NWkA; z=3ItKm<75!OJW+&D$A{Hj;iAiqMV=8XM;ZgsAdB^!yWwYjRG$ZU5hy-+8aTb?))Rn z-_}J8GyM?V&2UljC2(B3tP2DC$oD?+C6=X{{Bs59VFxD$-q*^e{MyWocxd3uXTqe=9Ej5x+PYQ zji%D><$y~LInd!znBvyvbW*s-ur7wtc)yXyDKsvyg*k1xh1 zy|^!36WFUxzX7*zY~R@eEa0dn;iwl-kT){0sroRl+3Y^l?E6mTbTRZk1X<$jjMO9G z#S*4^=P<)bB4GSKX$b%!?st2rH~cMhL_>2sGKv9rrKhjLJQqz(s4BzM#O;`UzYOJD z?n&EP&nU}T0N}TFGZ=6KM!%-FRPxg0LoBxny#RKPvgn|y^anf9h+a&|V&dYc10+N5hK+pulUC!tFXmZ$TGH|C&I1~c=i51 zn0hJEIb&;7R5_q~_h>chP;d@Sk~nK3A-?!QTg>=v2X8i7sv zvKpW$6O!#yiWn!7{!Ij)V8Rhkw!!G2%T`cq{*%!}Kt>}*x^rPttwecLmuH52Q6!y> z5VQ4XfCnni>?-isZYo6|0tCV3ZBFXCJ*-zvU)JqjU?tx& zz7&}5SGmsBS%%2gv!`B>yqL!jdYjV+5q!M1>BhHZ4oGXu&gQ4BUCaEpAGM~zK7Hlw z;qM!7@V%TfhyGm>>UsNRX-9lk+CR!m>5sfF%Ei|0UsdQK4piW!Uh?~^D%0H0;#*_v zG_pfmLuFIG9!ie;vbsZ=Qaq!OC*0l-m7how(Pegov@0MFwcR2gu7{3@;H zCo^w1Kmbg{sO!^lJH)I&+gZ)lQk69d4C|P1r%HtkqPXp*!!|@Cam1u(DK!gooyGi^Y)xT4%uzZ#ADS4k2T0!Z5vFYgv$+^p8rr_I1QK?5}= zg<>i@WV{R=P}hCdCG!fVt~91m1@R%P^W4Xc3tJxL7tc=jA!g?LtpLEcV_v+?C_B`< z!30dj>XzOvu(Sj(6`p+i3x2;N`XLeWF?9)TsRqX6+xQdb$$(}Gstiy$s}wQ_P1$@C zW^ty39gij`2Y(>?r;!8xf09R}2Z<3-mxmQdH2d5cj)Q}vTFJfKn*L1%P-SyG6cY>qjE=P?Z$&cy|6_8<-smxSe#YurS zYOYU+6tb_wWd@^iu3w4tGZQjGnpW1DsJCr@9NN=y>D)B|AoholWw~J7$9BCxcQk%N zI{EdssL1VLZJ8qJ3a+_!m0bDzGzd>0-{U|-m6Navq!a$ssAl%ALW;Lia3;8I>Sgqt z(PkH*j*B(d8>fEFS@3^E&HiVx%>NCC&UpcKW%3CsAN8%mRI0xuv8;SLRjCunNY-;T zdce3H8^7FI%D=ff1Gd?$8=sl?tGbJR{%o7giYc*McVHb15a>JG_3&@vrEYrd?5nZF zyM`8)!2$wFZyX2V<6t8nsW;U1IL2`b4N($j>D9*xkp8IV1j3Kw7maW_kmY?514%8J ziTvOwv&;BDelK--1zC=ov#|AgyoQ$71?R4f8pOtn@B`!Pp5K#|eW(6%g zq`j#6v$33h|8%qu0m9+C9o2qT_2C`e;ZNesLF0Q=13&{>39q)yX>vC0(ZUApihhMc zmN3B(3$@wyQ>VfXYA5a9Y(;H^O3UMQ`{TJ`#rhZpZEsB3WNlCTp^5qO_9ptZP0xvD z^_198cf32gJrC~H%fFhk(T>6^Ol4GITv_pFq(@qbjWtH-P$7vC>UY@|tOHO3vINi>)lX!DDmxXw zb|`NCK=wNqMEqmbJzK6}pRKW@lb<7?pwwI{SM5_*EXXH}@IGKD`U0b}ZHD4Y^Wuw1 zwrsuAA^umJTgy)FL_+eq!rteh-kO~BPRi+vLJF(g zmW83962>;dc@~N9O;8X(Ne~6U@}4o#iA_V<_g);f;*NAGH-Y*Bi~jdXb4rD+6~^}y zS>p+4jdUzbYhrKjB;c`*go0uHVP zpk1Ih5s*sh+CQm+^0}v1906o83?1GltoRhQ@ZF;26|DPgZ`Gc;on*1ka6zc$xk+*^ zslI^CJyl6Ravnpd)w!^lh@&QQ0jk8VTL zOlehxDc(f|o{G|)QX%b>SZ|J>xaWzNe)-`e?qB`IO>!cBw?l@t3+dP0qYhItmgZ-Q6AQBP_j7@mmk+mc&2v$-M1ej#) z$KR=#QF?mJqaP-eTC61Vgt~R7%ti2{bzf9G zdj>E9@@q&s`|)2`Qr#+8O(#X=@(w8kfgGK)kxPV7kIIJsV`;rHj!9Hmut}k42%%vC zGmLL4Lb294)GDAvh@HbJo`Gk3yJ{wfL#<6l{Z zzp3&j;5Tl2!v54`qbeY7S7r0!jhI}{tZHk^q5CpY6@i86t1lj;oyvC`?yMj4RrN;6c!%1BQL~ zcOb)rL>f0VsnTt&?6Fus=YUWg9C&7&V=aa!F<&*Vx!j~cRu2;Eka3L6zd{oYA?^1j z66=O&xT^-Z2Yg1|D`MUC9HeDO>ye{P!S^RG|BILns^-i8Hs3njTaK_n2xNjdqd4Jz z#GXpqk{CA$r$n0*Co;G_pc6elVqz2xITZ!rm}ADpN!LzQW{Q(Zxrui@VnmUJ&;CwU zg@XUcargA5n={O5>V8Pg&+sG1#ZK`^Xu@+W?SOl$Ji1O*p}6S7W;5;Yj1BkV&!W^z zYdZPRo5&_85kk`24CAUM`yJ~EUl5`}*u&9>Sir|T68C%xcJCOyZVRUEKXpg^Ilzhi4B$7_eJESQZf`^fol`Wk@{b6PE z{WXZlg3S;}g?s{%dwIV~WOqU0jvMM2%O9}<0j-`E=~8qh)RZ$p?v=|14lx|4&?L*^ zA_6qPgKVa#H7{2hbA}9Vk)du<^BthlrJ>eO%6s&@Z`T843)K8_9 z=$bhuBTJK%ha))8+@fCOy`^$rwwb7SW``cEeL==A&ia@ty2inJ<-!J;SVlDb3W zofK-@*GD4agbb{?`P*haYE4hXRhF*=^<>(_?bDqeSVUD;k0N`)$FN#&_WGztWj!7B2bW2;^c`TX~|467OTqgmX3!hewQ-V(v(iu z=+Aka(76x}%QZ=u;h&@XqMbiBN7wK$j(7rK+a9)Q7GMkB)D{87cbI>&2`;BNBT!l$ zav-x;2@SQ1!F-MiJEp9)@if##TsF=n5cLOooNbr7u!c!q1P(;k8pPl+3!zO$XQ@mP zQi@;qO^Gi;e#MFcrU^`b+tOjRPam1XnbeAL;&Iae%k~-w2YH7Zl@XHkYg+U9)gXFa4yl7B85I2cq-<*8Xw&*HnOh_mk1*5Z}mEZx^ z)aUl4GBkDkFsL!}My;MW+Br|RMWvKq@h%ib(!R}!)5#ayWoAo#E1-v`St15;uGvkt zPltCaYkXcWve=a(fQL-MOvE5xVJRs>PD;k>I5CKs;8)Xq_4(vo$qnWn)$#Tgjew)> zPL+M4r+l((i#t^Rrt5(}y0!u$pG$iHhe;k#mqRh0_=Dc18uxu;6nSA_l9mHK>vA;I zE^;A;r$oijtnUjbT6^6spyE;{*{w^PdtaZEow(VB=bl~wq|l)AXD9&()NC_^Z@HtP z;X?|i8S3cIdYShBP%E~~x@*x8t;TeU7J|wnZa%^s26*_S!!v@e>Bf5x34BfjS5G&l zDoCbN#y`m8l)$3Yts9P*RU*S;XFkk&CfR|X<|m2JYhP6u*zuV~97q4n`C#YPdVsX* zKnjOdPoQO0q0=8EM*Wi$a&GO(J5}w|mT~oI*N7=0G+L2P4&vbAM?(&rH`imUat&C_ zOw9W7R7X*XjFMtFkBaSqO{<2MZI4$_5(gR{#zEPJXDG_2q-j;$7{8*KdP$#bzGc{- zsC*Z3Q^?i}+*TCqwAK;vzRh9j>)eR-?Bplp%T>dlg4&Mj_gWagAV%=qJ<8JQgll`Cj77 zLZep9ltssIF}_M)P2cGp*LTs$r1w*e@yartEil67^Cq% zS(-9pmkBh?S~Ir%dYd^_Y<3FEpIQ{h2-9h=k3pRXH1fvn zS^b@hb_m}Ma$(+qE}qKL z#%-4{yc*P_E9(DFfK7rBA|4{uR=>G;nK1YOCzhJ#pl>S= zLaT+hw^1SDES{9F!?CX6oCsaYXHI{en)RhttN#lfn!Q{($)FG?)yKu>l)1&#eQmw5 zo-DyTnUa-IG+Xb#XR3i1?2G&elr!RI4*wk%pirS1a$~TPb(8-Tz~&VWs{1UBzvD~L z!%>1F=2(6t^BTo69ldhh)vn7~v~+oMrV_$lWjx5gpVL8xOabcid$^&B6ET=5b5iYr`X^o;eSYSy$e9D5CDzM6|$6@p+36ZIN(3m(x4hd(1Sq1K&tSOl1XD^1> zeZjMrZuCHg?@yYFp=S-}&G%UF$6@x~PLne?{4&K)I<+|nOA<5{&_*T27;0E?oa49j zg0GD&0=hTfH4%$D56EYemG~CU+^1MY`MkU{-B`#Ym2p3XmWT7%&VXwBcQz}*o=E3q z`iJWOWk_58KP&N*e<-3tWKI}Wx%4FKAyjw4qy!FR3e(8SjR_~`47Rc<%Y1=jxMK)r zdMRTHP6j)?F&NHf>@toOr=7K&WMErhcv`AIB~C>qo5)K`DCKx5=aAd3_%d0ZA@;FF z4*kRIq_`gog0|IHoNB_4eGSyHfV)#`D(O_PqyK$`bHGJXmpuPmquE?>ZGm5Z(I z@3uXso+gwUb?W3aP-kD1hw(boHwLE++lZ=cye?hWf~9=LW+l<A}VRw&u>?-mQym@HKm>tXI)bBIJu<_&mWS{f74bZsp0SM>nTV^EFpOFZC^hm*a zI?>9u^QXl^{Wrw`2}4zE;TWFq!aWIadD|Qi=8SXplaGg;+X&}3V+lWcF69x6W05dYH7YHErCqn+Bh3->O)6hI z>{+fqk~nO^+RHo;i0ZLqlu{bcVMy7FRRT4wGM;+p4s8oC>}SW2r>@F)kA^>5u&<*P zY?@^vhDF@0x+LV`M4&C${W`9iM)I(285T;N~yVe!5?A$v@CL_>vln z)cJ_8?R$?&_mXns8v?{ovjS$J;IbUF*jVxjH3n?_OyTD%PxmxL76! zD1J#XkPK*Y-9pC~y>EzPP8TfWOhbmoo@SYIP=p+g=!>JSYvux1E0Ogj@W`^H=kJ6U z>(6Engf(|X(CG$4KI$fo8lIF)24_l|RqR)d6Qsv8j%)C2Dza$QpWZ+1bCQtO$?&TZ z8Yc7tZ^R|9ufE}sZdbfk4~`3`R(}P#VtDT^Flt}%Ku$e0_mQeR299_OBOk0V4FsP3 zFdl(c?uS)1J?=Z^)F~d%fd6petv?wG;+k>H6Zz3>aHAH{9Y%e*EkU{ODzb*?h{7e< z8eQq+*H>u6BlPZNFdL!5+X)7J@6;KAx@&B}g(|$|TK6P@!1Li};l2~2fyddeW~D{f zG9{dTDrZvqKww!QJU=|E5UyUZl%^S#1N2%}4ypH1;8*>T5AKh|#y)EgY1+}HLb(?4 zs*k1Ow1xcsIrbI&lga>kCr1Lu7OqKT!8p~ZXjc?Sh)k~fg`~|P;t829_?k(Pa=a!G zAuQM#ut&N)@zUdLP6@52I0pMnDSgdc@+e&u2j${9!M^ZDS98b=QC_4m4N?bcVdN?^ z`TI~Axi2-3kBU#VC&ncAy&c}Aw*d_;w>C76^Rg$@#pNZJRgbh2%+Fph%DevQm)18m zoH^_CT9$>|1k@e5g3;e!842yGRQPoly6iHgh$q#*pNsa}mU>1nDC*qw9;J*&PX~1mNmm;L+q$pJO|ES!k-}5^J45%$LAK)2-z`aq z@^@wj$H!-Aq8aFTav6}_pe*T1@rc98LS(l}tl^-=i7&q?HJ5F-bl~qeQ%A4Ho2fu7nQv;+$)}!z4Km+MQ2oNUdZa8)Fs(#U4pex4KPuM2;B2S#w97N9w7p#Qr} z!iWvf$W07EFssk?te1RV0X6eMhPMg>ac=OgkYS9WQ1Rw1uX-`66;)$(c~UTa!NK8y zCzRZ^SZ|{URAw5m3#%I}`-*H>kN8C;p$&O0mAYfxdDRA`e%OyWUE76As%HVdnk>9& z!0)1kTPw36fR)ElCRnZ-(Fj|aKy!fNfv;Vm%qoBksc5eY@g6 z?qVMy1atsL-T`PF(6oJ7HG(I%akj&0z$&1}Q>J-_Em)2x8iKEy;HKoC1Ha%3^(

YqswFfQMTk>I0h;$1fPHGVirOqWcgkQ=re-AUhB=!mIrO;V8 zyjbhGMp>rpP$3?7fZQ9z2cZ%Ti!_5gC;->>&H78wrjYXHt~=lJ2asj?p|B0~K{`Jz zt}XP+V`L?Ux^;|InngemC==6#2r@+j#Nmv z!_XZP0us{Qf|PVgD~KrHfS31k-Ou}c|G_ykXYak%`mMEgUj8h!JRT$~FUOp|DkwkT zkms;sfV*bqm*P@xo63wjz91S7z&s6565cA!=r*#V*9wj+mOsNy^1P0TjWT@u2Hi|# zXXe`EUkF^#zJmHNy%6b;tFa@$9qD~p>2>+{ccu>;gjTZRni{a~di*Mvc1MYM_%mO2 zDXi{gAu(rORQN|dKZ3HiKt;{LE>6U%a9tR~m(^Doc}$?s=H+>~nO&z#4V-+~nB1Nx z!>FtMAk(KeJdTO(;nkjG()5}@5A-;H#`rM(0wsR}-gJ4z;UH>VG%aXx3XVl_>jkn4 zpjA;{NEaz7`!~OpSQ7Gezu>2-uM9N5_OMYwxqDoiyJW!i`XuoVe0>u0Y>(=>;3&Fy zo}WKe3BWso9@*;udN-k#T-7na{)H`{s&au0LwmiI>Hw6~n+fN<+}$4-9rN6{#7Dxh zhkufFIW(g`nu<_;%jkQ`uoOVZGsw&-@qn@9y((BpIkHxVbYukHq9#S40uAKOIEqBorpRpE$+kPo#CaSon_E zu(H{wdbp-&`iM&)dyH)hNUBt0*7Q!bBmAXN^?GovI|A+c5Nb@<`^bruI2@fhYDj8HSK$Cot& z6ASJz0&o`>BIRxrkL7jthpEugjBOZ8E|3;g95T7zLbJ6vOYa z5#p2Qn*FH_8w8b}Zr8wvZSaYIL#@j6jI6X5l$}G6LCfI7Bh+E!XOQx9XDVtv)J^kD zdS687))QY6e+#^ikB}iEOU&QuHrQr0_m{A}RC(XJrYie}zf}rC&8v*mBZn=wZO;cq z7mS_2E{nO);p4)gfUX0dXkm82MW&)p%fX;L24^|H7FH%KVpn?Ib! z@&rbSUidrGMRHslhxdP;bnMGtREK2$d7_9<_MC#UdC?&?;s6^BHjdOu=zCgJrA#7K zMMd3ZyAq<=N@z_)r7I}bMMKWpf_R*~;M3E0qh88p@M({L;RA8I3Ac*L4>tfG5MrQ2^L*gyUEsU3=(f=FrR-TlOGO|NvXsoVyIlLF$itsS3jyF9RxHlctO%ji*`g)ouX(uepp;oJQ#$22uZK}$wn-5!saRLV>ncZawWw1!G z7}$27k$#`3A}nhgRR{1vXlja*SM9kz);FmzMPuJ&X`YQb6 zF<;oaDxR^d?F$zsv?lqnPlLh+J|BeFk%s2Mu{l!J`Iq~b2hkGx$b{0DtxR{M*Wpd+ zZEz{%4HnW=!k!_A36V_gT|#MH4FD{+OJr-xTzVwgoi&WT;}@$2up z08Z|aybq)LrrLMAd7CqtJ7ExrVME9yg&|8S!4~e~z-w+nB^PGWC;_bu^BUT0UnOJ3rg}*4H8)hu8k&KyR}3 zaapE?$~5)9Zni*|5ier;nhT#qoU}nY@Clx4j@7M!$r4*8cPO%nT;ro~zADQS4VNh04h++qyGU zt0d$`_TN}CJ@ZugE?)MV|gi*>25$~lm1B9HyDK`J!8o6kU2QwNy9y%>a*ti4Wj5ds%bJCv}li=4(nUp z9w&z61jUpwB@w3LDd?>#C0@`Olr5G0(5rc(D3^Q|r@IabeOBSmE$Wd{r;4?{3z<*g z4q9a|5HUH4OC3)~JXGxPA|=4JkTpDe$)$uAV8Dbn(Rs>$`Vy6rh9!tNpqq45|I}qS z*m$8hj9V>HQuuWR(O>E1&*bjPXsG}kn(nqX@b_Dw>G&_ifE-lj5ER;v#sEQBkM&%S zZ31a-Xc#F5p?btjQ;ncfVdOR@M{i{%$)Pas;i+nZO(&GhOuEQ7A3;Ae`oxPT!WzR* znXoz$tDqFjq>t63%P8c+maOGFfoFrm^Nb$2n(-uu2$j~L$wp4*%1RLrtcelv#_4*8 zOWF@XUQKYyLR5qd;r(w^8mjsyD-)7^7wWuxga9ii*Y-dk-w?@v1*Fp%kOy>Kp0@8)X=Runw<>EL1%1cXT15ZIX^1_~yRs%U zq9bj5tNedYc<)eyps0YxpS`U6~)WNL`BnBy|`!X?3 zF;{Y38{VoAUsM@*yt0~sqHqGREWvm#TGfcjLWML#9lg|wKF;~cqbChKULr`XwhkFZ zbEaD;-#hvHhbx+Ym54mwOqW+L2EitFt4@aRTw>8j9QFymzh9Foi_A0J&$jsxU5>aST@VYrg9P{ydX-6m_1-3_cctsy!8$2t&!xFhC@*=0yiisPBaHOb#MK_-u+O}4F^nN)Wh zzF|es-RIe0IrSNU3%q__0m~3J>(3hkiOkF*Qr&K$;rA9${t||J zMI)&ys!IwbB7Fw1`teX4fYG3)#VwIFn-BwFx{k1x>L?3DqtnUzxTe81DRmD3u=%AP z>j?f}e2;E&(VEysHxS; zYvrY~4L0d=s5QGn&Ol%DLJR!4IH?nHbCkwou&OCI$WMAziX=0PYr02I@JZ)E&cD57 zcR-|WYT?fY?#q0qb9)wjuTs%o3p~S1${V{tn2YKO*~&D_`faWBvBlwZ-*c}x#e*oL z)g5^kxbt<`Y<%+kFvDZ+X$i7A*-uSrv>K+{<-%cQFT<1P56!Op$mcbd7CfwFcOgd2 za)w~6)*{h7N7i_9Y^E^=McMosyejGZh#>BTzH6y}5G4N_HPpe%JtLGRTd+90EwVGihFtz0T8}$7Hz)&&{ zE+lsFHcGTn=VX~yMo~k#M{cEdqWKcxEF3KMl$Z)sfzA;vAeu)ltd}+i5Jr&4ZBokf z!yZ=F5L6h9LEyxMG*ujRGUsJLDdNriXSjy!61Gq`lr|yq=E01dg61&4=gez}y13$_ z+VbCj$F%=z1t7C|@V;A;9zqj}40UFv4qW~O-ojuG! zJVrUi@WvACx9UUSchLXz!O{JSAb0_!$Bl_O{jCm!2$U&1g1IW5%pkZsXd49WIWzEU za~~VMZ#ct9Uf%!2C8NM;PFi-xV|#IxYO?k1w7;cr1OUfh6$YCJX& zwZ}FF1P;Wmp){T3be>^;^8fd3?-zh~&+dG#*ATH}#6iagW_4v`?{z6N9sWz=@v29C zQi22kn7e==8=Y7y{sF3=&ul#LjG*J!MaHB6A)!$CLE?eZ%8%hi##k0~Ei>?{@K5M# zCBN(@i6f2VVS_C_2`z$FjtdW|uuvZRfa^-ZmTw>?J*Q`^I6bfeaU}sNLfbAA z4x(D4WsBtoaY-3R;#S$^?bEYrs*88~*a{!Qt1lo@8&u81P!R>CbPZ~2sx~+QsQD|f zdSN2p14qXInX;a-5_2~<5R32&im5}7Ak4Iy%HwclKnT;_7;KJxEM3YJ>VZ1cxbs9; zCsb-_B7+ZZ=At{QcZ2V1TD1@1+3Om@eNe~KGhDm_ZwFbeAYX=;`u0hek?&0A*McC8 zK~7x!)?i&BU2hQMv=SQmCJl6Mre9uSL3`Fhi)VyWg*@10|MkGf`2uXuoO{eYn4!?v zTm!ENg#DEyuf_NMozzqwroAZ6hxXa^r7v4z*!oX~V}9`k2NuUhH1`8SIy!Aah;b}N zpHdL@=J*OG_7ykC`zDH;PgKkq>Q2w}h19K&)XX^|Eo1-BzK{63?-#B9*S;T$cFv81 z|73J1NXbxNmTkbtA7-y;1qOCNN)`(sFP?7o@<2H4hvie+6iP_0t$s-RQkk!*c0Trf zh~n=m=WltT-Eej&t?VinP;Go~W?De&7!CY;qAbG$Mu`4e@s%Bpu0#Z5)|-$ zd8qoiCuIw#K|#@@_(v;&>^n|5w8}8`sL3cIbALEo2Be%dijBgJ2!ft9eBq`9l_n{u z7HK*=bErBMqA~1fK1P5O;y`?ujcWGX6LC~>%6%#F!B^3X+yo9w-&1j?@zr1!=f*+Q zu`ZlWiKq43S@3|4lcy-;FatEK0T6Wl9Wz;v9mwNDn^HUWNUEwD3fZW!xr_+qb3*je z^i=-Mg8vdk1Vz8T-|Gg+-del4|7s%0Aaw$S=^Fis5T^9~4~D+&RH;CavO!sYpY-QI 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

WY41-#Zxi*`fI(DT8!nP0S$$L7fA3 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 issue). +- Updating `VaultPackage` must only take place after calling the `migrate` function in the old `VaultPackage`. +- Updating `VaultPackage` must only take place if the migration of balances to the new `VaultPackage` was successful. + +#### [NEW] There is no emergency suspension of the rewards payment in the `VaultPackage` contract[DONE] +##### Description +In the `VaultPackage` contract there is no possibility to suspend the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31). This causes the attacker to continue taking tokens from the contract if the address with `REWARDS_OPERATOR_ROLE`, such as `StakingHandlers` contract, is compromised. + +##### Recommendation +We recommend adding the `pausable` modifier to the `payRewards` function of the `VaultPackage` contract. + +#### [NEW] Unsafe use of the `transfer` and `transferFrom` functions in `StakingHandlers` and `VaultPackage`[DONE] +##### Description +In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L34) and [VaultPackage](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) contracts there are unsafe `transfer` and `transferFrom` functions of the `ERC20` standard. The use of these functions is not recommended as not all tokens clearly comply with the `ERC20` standard, more details [here](https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca). +##### Recommendation +We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) extension from the OpenZepplin library and replace the `transfer` and `transferFrom` calls with `safeTransfer` and `safeTransferFrom`. + +#### [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`{DONE} +##### Description +In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. + +##### Recommendation +We recommend: + +- adding a separate `deposit` function in the `VaultPackage` contract and make reward payments through the `deposited` parameter. +- adding a separate `withdraw` function that would allow the `DEFAULT_ADMIN_ROLE` address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). +- replacing [token transfers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) to `VaultPackage` in the `StakingHandlers` contract with calling the `deposit` function of the `VaultPackage` contract. It should have a prior `safeApprove` call to token in the `VaultPackage` contract. + +#### [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[NOTDONE] +##### Description +In the `StakingHandlers` contract the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function does not allocate tokens for rewards `MAIN_STREAM`, as it happens when [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) is called. This may result in the block of the `withdrawStream` function call from the `MAIN_STREAM` of tokens and rewards for some users, if the amount in `VaultPackage` is less than the amount stated in `scheduleRewards`. +##### Recommendation +We recommend moving the initialization of `MAIN_STREAM` from `initializeStaking`, that can be called when creating [`StakingProxy.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/proxy/StakingProxy.sol#L7), to the `initializeMainStream` function, which can only be called by `STREAM_MANAGER_ROLE`. Before calling this function the work of the contract must be suspended. + +#### [NEW] Updating `rpsDuringLastClaimForLock` for inactive `stream` in the `StakingInternals` contract[DONE] +##### Description +In the `StakingInternals` contract when the `_stake` function is called the [calculation of `rpsDuringLastClaimForLock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L123) is done even for inactive `streams`. This can lead to both excessive gas consumption and denial of service if the number of `streams`, active and inactive, is too large. +##### Recommendation +We recommend adding a check that the `stream`, for which the check takes place, has `ACTIVE` status. + +#### [NEW] There is a possibility for a manager to remove all streams in order to steal all pending rewards in `StakingHandlers` [DONE] + +##### Description + +In the contract `StakingHandlers` in the [`removeStream`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L163-L178) function a manager can remove `stream` with pending rewards for users. This will result in users losing their pending rewards. + +##### Recommendation +We recommend adding logic to check that there are no pending rewards for users in the `stream` before it can be deleted. + + +#### [NEW] `MINTER_ROLE` and `WHITELISTER_ROLE` have the same value in the `VMainToken`[DONE] + +##### Description + +In the contract [`VMainToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L14-L15) the `MINTER_ROLE` and `WHITELISTER_ROLE` constants have the same value: +```solidity +bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); +bytes32 public constant WHITELISTER_ROLE = keccak256("MINTER_ROLE"); +``` +When the role is set, the `WHITELISTER_ROLE` variable will in fact be set to the `MINTER_ROLE`. This will result in the user getting both roles and an address with `WHITELISTER_ROLE` being able to call the `mint` and `burn` functions. + +##### Recommendation + +We recommend updating the setting of `WHITELISTER_ROLE` constant: + +```Solidity +bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); +``` + + +#### [NEW] Transaction should be marked as `executed` if the call fails[DONE, understand more] + +##### Description + +In the contracts: + +- [`MultiSigWallet.sol#L137-L145)`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L137-L145) +- [`TimelockController.sol#L111`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) +- [`Governor.sol#L76`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) + +If the call fails, all the state changes of the contract will be reverted. It means that this call would not be marked as `executed` and can be repeated in the future, since it has enough confirmations. + +##### Recommendation +We recommend marking transaction as `executed` in all cases, removing lines with statement of revert failed transactions, and adding `data` value to event. + + +#### [NEW] Admin role can be revoked forever by mistake in `VMainToken`[DONE] + +##### Description + +In the contract `VMainToken` in the [`initToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L32) function, the value of `admin` can be the same as `msg.sender` and thus it becomes possible that an `admin` accidently revokes admin role from himself. + +##### Recommendation + +We recommend adding a check that `admin` is not equal to `msg.sender`. + + +#### [NEW] It is possible for attacker to create active locks to force users to reach the lock limit in `StakingHandlers`[NOTDONE] + +##### Description + +In the [`StakingHandler`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L180-L187) contract the attacker can create active locks for token holders with `createLockWithoutEarlyWithdraw` function by using max value for `lockPeriod` in multiple transactions. In this case user's locks limit can be reached and they will not be able to enter the staking until the end of the lock period. + +##### Recommendation + +We recommend: + +1. Revising the logic of the `createLock` and `createLockWithoutEarlyWithdraw` functions and making a separate limit for creating a lock from a third-party address. +2. Or creating a lock from the `msg.sender` address. + +#### [NEW] `prohibitedEarlyWithdraw` is not set to `false` for `lockid` after unlocking in `StakingHandlers`[DONE] +##### Description +In the function [`createLockWithoutEarlyWithdraw`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L181) in the `StakingHandlers` contract parameter `prohibitedEarlyWithdraw` for given `lockid` is set to `true`, but it does not update to `false` after unlocking later in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions. Since the value in the `locks` array is deleted after the unlock, all new values will be assigned the value of `prohibitedEarlyWithdraw`, regardless of whether the `createLockWithoutEarlyWithdraw` or `createLock` function is called. + +##### Recommendation +We recommend setting `prohibitedEarlyWithdraw[account][lockId]` to `false` before deleting value from `locks` array in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions: + +```solidity +prohibitedEarlyWithdraw[msg.sender][lockId] = false; +``` + +#### [NEW] Calling `unlock`, `earlyUnlock` and `unlockPartially` before `claimRewards` will result in loss of rewards in `StakingHandlers`[Frontend Will Handle] +##### Description +In the contract `StakingHandlers` the following functions can cause a loss of rewards if they are called before `claimRewards`: + +- [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) +- [`earlyUnlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L207) +- [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) + +It is possible because: + +- `unlock` and `earlyUnlock` functions contain an internal call to the [`_unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L76), where `lock` with given `lockId` is [removed](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L146) +- in `unlockPartially` the `rpsDuringLastClaimForLock` for given `lockId` is [updated](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L150) + +As a result, rewards for given `lockId` will be lost. + +##### Recommendation +We recommend adding internal function `_claimRewards` and claim rewards with the calls to `unlock`, `earlyUnlock`, and `unlockPartially` functions. + + +#### [NEW] Share weight drop formula is incorrect in `StakingInternals`[DONE] + +##### Description + +In the `StakingInternals` contract [share weight drop formula](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L228) is incorrect: +```solidity +uint256 shares = amountOfTokenShares + (voteShareCoef * nVoteToken) / 1000; +uint256 slopeStart = streams[MAIN_STREAM].schedule.time[0] + ONE_MONTH; +uint256 slopeEnd = slopeStart + ONE_YEAR; +if (timestamp <= slopeStart) return shares * weight.maxWeightShares; +if (timestamp >= slopeEnd) return shares * weight.minWeightShares; +return + shares * + weight.maxWeightShares + + (shares * (weight.maxWeightShares - weight.minWeightShares) * (slopeEnd - timestamp)) / + (slopeEnd - slopeStart); +``` + +It appears that the weight of the shares should gradually fall over time from `weight.maxWeightShares` to `weight.minWeightShares`. + +However, the current formula implements a weight drop from (2*`weight.maxWeightShares` - `weight.minWeightShares`) to `weight.maxWeightShares`. + +##### Recommendation + +We recommend changing `weight.maxWeightShares` to `weight.minWeightShares` in weight drop formula: + +```solidity +return + shares * + weight.minWeightShares + + (shares * (weight.maxWeightShares - weight.minWeightShares) * (slopeEnd - timestamp)) / + (slopeEnd - slopeStart); +``` + + +#### [NEW] Penalty can be bigger than stake in the `StakingInternals`[DONE, but readability part NOTDONE] + +##### Description + +In the contract `StakingInternals` there is a [penalty calculation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L181) in the `_earlyUnlock` function: + +```solidity +uint256 penalty = (weighingCoef * amount) / 100000; +user storage userAccount = users[account]; +userAccount.pendings[MAIN_STREAM] -= penalty; +``` + +The maximum value of the `weightingCoef` that it can take is `weight.penaltyWeightMultiplier * weight.maxWeightPenalty`. In this case, the weight parameters are not checked in any way during [initizalization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33). If they are set in a way that the product of `weight.penaltyWeightMultiplier * weight.maxWeightPenalty` is greater than `100000`, then the penalty will be greater than the amount, which in turn will lead to excessive pendings or overflow. + +##### Recommendation +We recommend adding the following check to `initializeStaking()` and `updateConfig()`: +```solidity +require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "Wrong penalty weight"); +``` +It is also worth moving the value of `100000` into a separate constant variable to improve the readability of the code. + + +### WARNING + +#### [NEW] Modifier `onlyOwnerOrGov` creates a complex confirmation structure in case of `Governance` calls in the `MultiSigWallet.sol` +##### Description +The modifier [`onlyOwnerOrGov`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L29) uses the following construction: +```solidity +require(isOwner[msg.sender] || governor == msg.sender, "MultiSig: MultiSigWallet, onlyOwnerOrGov(): Neither owner nor governor"); +``` +that allows calling the following functions in the contract on behalf of Governance: + +- `submitTransaction` +- `confirmTransaction` +- `revokeConfirmation` + +However, `Governance` may commit contract calls only with [permission from `MultiSigWallet`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L173). + +The result is that, if `Governance` wants to call a transaction on a `MultiSigWallet` contract: + +- `Governance` creates `proposal` for a call to `MultiSigWallet`. +- `MultiSigWallet` after confirmation by owners must call `confirmProposal` on `Governance`. +- Then `Governance` may call one of `MultiSigWallet` functions. +- In this case, however, `MultiSigWallet` transaction execution still requires signature of `owners`. + +Schematically, is looks like the following: + +- To make a call for `MultiSigWallet` it takes steps: `Governance` -> `createProposal` -> `confirmProposal`. +- To execute `confirmProposal` it takes steps: `MultiSigWallet` -> `submitTransaction` -> `confirmTransaction` -> `executeTransaction`. +- To make a call for `MultiSigWallet` it requires the next steps from `Governance`: `Governance` -> `execute` -> `MultiSigWallet`. + +And so each function in the sequence: + +- `submitTransaction` +- `confirmTransaction` +- `revokeConfirmation` + + +##### Recommendation +We recommend removing `Governance` from this modifier and give the permission to `MultiSigWallet` administration to authorized representatives only, or review the logic of `Governance` and approving of `proposals` from `MultiSigWallet`. + +#### [NEW] No parameter check when adding transaction in `MultiSigWallet` +##### Description +In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. +Based on the logic of the contract, there may be the following cases: + +- `_to` is a `EOA` address, `_value != 0,` `_data = ""`. +- `_to` is a contract. + +##### Recommendation +We recommend adding parameter checking when adding a transaction according to possible cases of using `MultiSigWallet`. + +#### [NEW] Missing validation, that the bytecode of address `_to` did not change while running a transaction in `MultiSigWallet` +##### Description +In the functions [`confirmTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L129) and [`executeTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L137) there's no validation that the bytecode of address `_to` did not change as an EOA or smart contract. +In this case, the following situations are possible: + +- when the transaction was added with the parameter `_to` as an EOA address, i.e. with an empty bytecode, and when the transaction is executed, frontrunning may occur and the attacker may deploy to `_to` address a smart contract with malicious code, using [metamorphic contracts](https://mixbytes.io/blog/pitfalls-of-using-cteate-cteate2-and-extcodesize-opcodes) and `create2` opcodes. +- when the transaction was added with the parameter `_to` as a smart contract, and at the moment of transaction execution, frontrunning may occur, and the attacker may change the bytecode at the `_to` address for a smart contract with malicious code using [metamorphic contracts](https://mixbytes.io/blog/pitfalls-of-using-cteate-cteate2-and-extcodesize-opcodes) and `create2` opcodes. + +##### Recommendation +We recommend adding: + +- checking that `_to` is an EOA address and when `confirmTransaction` and `executeTransaction` if the contract isn't deployed into the adress, using [`isContract`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L36) from OpenZeppelin. +- checking that the contract's bytecode has not been changed, recording the bytecode hash into a separate mapping, e.g.: +```solidity +bytes32 codeHash; +assembly { + codeHash = extcodehash(_to); +} + +isWhitelistedBytesCode[_to] = codeHash; + +... +bytes32 codeHash; +assembly { codeHash := extcodehash(account) } + +return (codeHash != isWhitelistedBytesCode[_to]); +``` + +#### [NEW] There's no ETH balance validation when adding a non-zero transaction `_value` in `MultiSigWallet` +##### Description +In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no verifying that `MultiSigWallet` account has the necessary amount on the balance for the transaction. In case of approval by `owners` , the transaction will be approved but not executed. + +##### Recommendation +We recommend adding balance check while adding a transaction with a non-zero value `_value`. + +#### [NEW] There is no time limit for executing proposal in `Governor.sol` +##### Description +The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract has no parameters for the time limit on `proposal` execution. This can result in no longer relevant proposal being executed after a period of time. +##### Recommendation +We recommend adding the `lifetime` parameter, the runtime of `proposal`, and check it during the execution. + + +#### [NEW] There is no check for gas consumption in `Governor` +##### Description +In the [Governor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L142) contract, the `propose` function lacks a parameter and a check for gas limit for calls to `targets`. This could make it possible for a call to a vulnerable external contract to be able to loop the call and perform a DDoS attack with high gas consumption. + +##### Recommendation +Consider implementing the `gasLimit` parameter - the maximum gas amount for a call, for each of the `targets`. + + +#### [NEW] `confirmProposal` is possible for both active and inactive proposals in `Governor` +##### Description +In the `Governor` contract the function [`confirmProposal`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L173) can be called for both active and inactive proposals. +##### Recommendation +We recommend adding a check that the proposal is either successful or already scheduled in the `confirmProposal` function: +```solidity +ProposalState status = state(proposalId); +require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); +``` + +#### [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController` +##### Description +In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) contracts the `execute` functions do not check the `msg.value` balance value needed to execute `_targets`, which would result in gas consumption even if the amount of `ETH` is not enough. +##### Recommendation +We recommend adding: + +- a check that the `msg.value` passed to the `execute` function is greater than the total value needed for the execution of the `targets` calls in the proposal. +- a return of the remaining `ETH` balance to the sender of the transaction after the execution of `proposal`. + +#### [NEW] There is no check for zero value for `_token`, `_multiSig` and `_timelock` in `Governor`, `GovernorTimelockControl`, `MainTokenGovernor` +##### Description +In the constructors of [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L67), [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L17) and [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L21) contracts it is possible to set zero values for `tokenAddress`, `_multiSig`, `timelock` contracts. + +This may cause that `_token`, `_multiSig` and `_timelock` can be set to a zero address by mistake and break the contract. Thus, it will not be possible to update these parameters because an update is only possible from `Governance`, and `Governance` will cannot update parameters if `_timelock` is zero. + +##### Recommendation +We recommend adding a validation that the `_token`, `_multiSig`, `_timelock` addresses in the constructor are not zero. + +#### [NEW] There is no check for zero in `GovernorSettings._setProposalThreshold`[DONE] +##### Description +In the [`_setProposalThreshold`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorSettings.sol#L59) function it is possible to set `_proposalThreshold` to `0`. This can lead to a proposer be able to create a proposal with no voting tokens on the balance, or with a minimum number of them (e.g. `1 wei`). This creates a DDoS attack threat. +##### Recommendation +We recommend adding a check that `newProposalThreshold` is not zero. + +#### [NEW] There is no limit on the number of proposals for one proposer in `Governor`[] +##### Description +In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. +##### Recommendation +We recommend adding a limit to the number of proposals with `active` and `pending` status. + +#### [NEW] A missing check that tokens are on the balance when calling the `payRewards` function in the `VaultPackage` contract +##### Description +In the `VaultPackage` contract when calling the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31) there is no processing of errors such as: + +- There is no check that tokens are on the balance. +- There is no check that the value of `amount != 0`. + +##### Recommendation +We recommend adding a check that tokens are on the balance and that `amount != 0`, and return error using `custom errors` (`revert CustomError`) or with `require`. + + +#### [NEW] There is no limit on the maximum number of active `streams` in the `StakingHandlers` contract +##### Description +In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) contract there is no limit on the maximum number of active `streams`. This creates a situation of an uncontrolled gas consumption when dealing with contract functions and can lead to DoS. +##### Recommendation +We recommend adding a parameter that would allow to limit the maximum number of active `streams`. + + +#### [NEW] Incorrect processing of contract modifiers `Initializable` in the `StakingHanders` contract +##### Description +The contract [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) uses the `upgradeable proxy` template, at the same time the work with the modifiers of the `Initializable` contract, which is inherited from the `AdminPausable`, is not performed correctly. +##### Recommendation +We recommend adjusting the contract according to [OpenZeppelin's recommendations](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/Initializable.sol): + +- The contract constructor must contain a call to the `_disableInitializers` function to disable contract initialization at the implementation level and prevent an attacker from using the contract's implementation +- The initializer (in the case of the `StakingHandlers` contract it is `initializeStaking`) must contain the `initializer` modifier +- The initialiser of the parent contract must be with the `onlyInitializing` modifier (in the case of the `StakingHandlers` contract, it is a call to the `pausableInit` of the [`AdminPausable`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/security/AdminPausable.sol#L28) contract) + +#### [NEW] It is possible for any user to call `createStream` in the `StakingHandlers` contract +##### Description +In the `StakingHandlers` contract any user can call the function [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L134) and run `stream`. This bears a risk that attackers could mislead a potential user into giving `approve` to the `StakingHandlers` contract and force them to call `createStream`. `createStream` will charge the user the necessary amount of money for the rewards. +##### Recommendation +We recommend adding a condition that `createStream` can only be called from the `streamOwner` address. + +#### [NEW] Possible overflow with calculations +##### Description +In the next lines there is a possible overflow: + +- [`RewardsLibrary.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L70) +- [`RewardsLibrary.sol#L71`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L71) +- [`RewardsLibrary.sol#L78`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L78) +- [`RewardsLibrary.sol#L8`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L84) +- [`RewardsCalculator.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L70) +- [`RewardsCalculator.sol#L77`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L77) +- [`RewardsCalculator.sol#L83`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L83) +- [`RewardsInternals.sol#L15`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsInternals.sol#L15) +- [`RewardsInternals.sol#L24-L25`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsInternals.sol#L24-L25) +- [`StakingInternals.sol#L47`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L47) +- [`StakingInternals.sol#L45`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L45) +- [`StakingInternals.sol#L227-L230`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L227-L230) + +##### Recommendation +We recommend to use [`muldiv`](https://xn--2-umb.com/21/muldiv/index.html) to multiply elements safely. +We also recommend to update `voteLockCoef` [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L42) and add checks that it is not zero (to prevent division by zero) and that it is not too big in order to avoid overflow in `BoringMath`. + + +#### [NEW] Multiple `streams` can be active at the same time with the same parameters in `StakingHandler.sol ` + +##### Description +In the contract [StakingHandler]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L103-L111) it is possible to add and activate `streams` with the same parameters. This can lead to duplicate `streams` with the same parameters executed by mistake. + + +##### Recommendation + +We recommend adding checks that `stream` is added before submitting a new one. + + +#### [NEW] There is no limit for the amount of schedules on streams in `StakingHandlers` + +##### Description + +There is no limit for the amount of schedules on streams in the contract [`StakingHandlers`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L103-L111). This can cause the block gas limit to be exceeded. + +##### Recommendation +We recommend limiting values of `scheduleTimes` or `scheduleRewards`. + + +#### [NEW] It is possible to remove tokens that are used by another contract in `VaultPackage` + +##### Description +Calling the [`removeSupportedToken`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L47-L51) function in the `VaultPackage` contract removes tokens which are used in the `StakingHandler` contract to pay rewards and staked tokens. + +##### Recommendation + +We recommend adding logic to check that tokens are not used in any other contract before removing them. + +### INFO + + +#### [NEW] There's no logging of reverted transactions in `MultiSigWallet` +##### Description +In the function [`executeConfirmation`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L144) there's no logging of failed transactions. +```solidity +(bool success, ) = transaction.to.call{ value: transaction.value }(transaction.data); +require(success, "tx failed"); +``` + +##### Recommendation +We recommend replace this construction for the next one: +```solidity +error TransactionRevered(bytes data); +... +(bool success, bytes data) = transaction.to.call{ value: transaction.value }(transaction.data); + +if (success) { + emit ExecuteTransaction(msg.sender, _txIndex); +} else { + revert TransactionRevered(data); +} +``` +This will allow monitoring of suspicious activity that involves using of `MultiSigWallet`. + + +#### [NEW] Non-optimal packing of the `Transaction` structure in `MultiSigWallet` +##### Description + +The structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) uses a non-optimized storage layout. + +##### Recommendation +We recommend optimizing storage layout the following way: + +```solidity +struct Transaction { + address to; + bool executed; + bytes data; + uint value; + uint numConfirmations; +} +``` + +#### [NEW] Incorrect status check in `execute` function in `Governor` +##### Description +In the [`execute`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) function there is an incorrect check of `Proposal` status: +```solidity +require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); +``` +In the [MainTokenGovernor.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract, that inherits from `Governor`, the execution is passed to the `TimelockController` contract. For a transaction to be executed through `TimelockController` it must only have the `ProposalState.Queued` status. Otherwise the gas will be wasted and the `execute` call will be reverted. +##### Recommendation +We recommend changing the status check for `Proposal`: +```solidity +require(status == ProposalState.Queued, "Governor: proposal not successful"); +``` + +#### [NEW] `_minDelay` can be set to zero in `TimelockController` +##### Description +In the `TimelockController` contract the `_minDelay` parameter can be set to `0` during [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L67) and in the [`updateDelay`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L149) function. This will result in batch being able to be executed in the same block it was queued for execution. + +##### Recommendation +We recommend adding a check that `_minDelay != 0`. + +#### [NEW] There is a redundant `initialized` check in `VMainToken` +##### Description +```solidity +require(!initialized, "already init"); +initialized = true; +``` +The [`initToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L24) function contains redundant code with checking and setting the value of the `initialized` parameter, since this check already exists in the `initializer` modifier in the `initToken` function. +##### Recommendation +We recommend deleting these lines. + + +#### [NEW] There is redundant code in the `VMainToken` contract +##### Description +The [`_mint`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L74) and [`_burn`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L78) functions in the `VMainToken.sol` contract are redundant and essentially do not overload the parent functions. +##### Recommendation +We recommend deleting these functions. + +#### [NEW] The `Governor` and `TimeLockController` do not support the `ERC721` and `ERC1155` tokens +##### Description +The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contracts lack the following methods: + +```solidity +/** + * @dev See {IERC721Receiver-onERC721Received}. + */ +function onERC721Received( + address, + address, + uint256, + bytes memory +) public virtual override returns (bytes4) { + return this.onERC721Received.selector; +} + +/** + * @dev See {IERC1155Receiver-onERC1155Received}. + */ +function onERC1155Received( + address, + address, + uint256, + uint256, + bytes memory +) public virtual override returns (bytes4) { + return this.onERC1155Received.selector; +} + +/** + * @dev See {IERC1155Receiver-onERC1155BatchReceived}. + */ +function onERC1155BatchReceived( + address, + address, + uint256[] memory, + uint256[] memory, + bytes memory +) public virtual override returns (bytes4) { + return this.onERC1155BatchReceived.selector; +} +``` + +Thus `Governor` and `TimeLockController` do not support tokens with `ERC721` and `ERC1155` standards. +##### Recommendation +We recommend implementing these functions if the `Governor` and `TimeLockController` contracts require support for the `ERC721` and `ERC1155` tokens. And also create a list of trusted tokens that can work with (see above - `ERC20` standard tokens transfer possibility). + +#### [NEW] The `addSupportedToken` and `removeSupportedToken` calls have an redundant `pausable` modifier in the `VaultPackage` contract +##### Description +In the `VaultPackage` contract the calls [`addSupportedToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L41) and [`removeSupportedToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L47) have a redundant modifier `pausable` since the calls are only possible from the `DEFAULT_ADMIN_ROLE` address and the modifier `pausable` contains the following condition +```solidity +require((paused & flag) == 0 || hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "paused contract"); +``` +where the `paused` condition will be ignored. + +##### Recommendation +We recommend reconsidering the `addSupportedToken` and `removeSupportedToken` function modifiers or removing the `pausable` modifier. + +#### [NEW] There are no checks that `admin`, `proposers` and `executors` are not zero addresses in `TimelockController` + +##### Description + +In the contract [`TimelockController`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L49-L69) constructor there are no checks that `admin`, `proposers` and `executors` are not zero addresses. + +##### Recommendation + +We recommend adding checks that `admin`, `proposers` and `executors` are not zero addresses. + +#### [NEW] Unused import of `StakingStructs` in `StakingStorage` + +##### Description + +[Import of `StakingStructs`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/StakingStorage.sol#L7) in the `StakingStorage`contract is never used. + + +##### Recommendation + +We recommend removing it to keep the codebase clean. + +#### [NEW] Unused constant `ONE_MONTH` in `StakingGettersHelper` + +##### Description + +The [`ONE_MONTH`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/helpers/StakingGettersHelper.sol#L13) constant in the `StakingGettersHelper` contract is never used. + +##### Recommendation +We recommend removing it to keep the codebase clean. + + +#### [NEW] Non-optimal storage layout for `Stream` struct in `StakingStructs` + +##### Description + +[`Stream` struct](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/StakingStructs.sol#L54-L66) in the `StakingStructs` contract has non-optimal storage layout. + +##### Recommendation +We recommend moving `StreamStatus` definition after the `rewardToken` line in the struct `Stream` in order to store values in one slot. +```solidity +struct Stream { + address owner; // stream owned by the ERC-20 reward token owner + address manager; // stream manager handled by Main stream manager role + address rewardToken; + StreamStatus status; + uint256 rewardDepositAmount; // the reward amount that has been deposited by a third party + uint256 rewardClaimedAmount; /// how much rewards have been claimed by stakers + uint256 maxDepositAmount; // maximum amount of deposit + uint256 minDepositAmount; // minimum amount of deposit + uint256 tau; // pending time prior reward release + uint256 rps; // Reward per share for a stream j>0 + Schedule schedule; +} +``` + +#### [NEW] Unnecessary `'` in a `RewardsLibrary` comment + +##### Description +There is an explicit `'` in the comment in [`RewardsLibrary.sol#L82`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L82) line. + +##### Recommendation +We recommend removing `'` from the comment. + + +#### [NEW] There is a typo in a comment in `StakingInternals` + +##### Description + +There is a typo in the word "have" in the following line [`StakingInternals.sol#L95`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L95). + +```solidity +// user does not hae enough voteToken, it is still able to burn and unlock +``` + +##### Recommendation +We recommend changing it to: +```solidity +// user does not have enough voteToken, it is still able to burn and unlock +``` + +#### [NEW] Redundant check for `maxDepositAmount > 0` in `RewardsCalculator` + +##### Description + +There is a redundant check for `maxDepositAmount > 0` in the next lines: + +- [RewardsCalculator.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L21-L23) +- [RewardsLibrary.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L21-L23) + +Since `minDepositAmount` is already greater than `0` and `maxDepositAmount` must be bigger than `minDepositAmount` there is no need to check that `maxDepositAmount > 0`. + +##### Recommendation + +We recommend removing requirement of `maxDepositAmount > 0` for gas savings and improving code readability. + + +#### [NEW] It is not possible to withdraw tokens that were sent by mistake + +##### Description + +It is not possible to withdraw tokens that were sent by mistake it the following contracts: + +- [`RewardsCalculator.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol) +- [`StakingPackage.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingPackage.sol) +- [`VMainToken.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) +- [`MainToken.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/MainToken.sol) + +##### Recommendation + +We recommend adding `sweep` function to withdraw tokens that were sent by mistake. + + +#### [NEW] Unused import of `ReentracyGuard` in `StakingHandlers` +##### Description +There is import of [`ReentracyGuard`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L11) in the `StakingHandlers` contract but `nonReentrant` from this class is never used in `StakingHandlers`. + +##### Recommendation +We recommend removing the unused import. + +#### [NEW] Сustom `initializer` modifier is used instead of one from OpenZeppelin + +##### Description + +It is better to use [Openzeppelin `initializer` ](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/Initializable.sol#L83) instead of custom modifiers in the next functions: + +- [`StakingHandler.sol#L33`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) +- [`VaultPackage.sol#L18`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L18) +- [`VMainToken.sol#L24`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L24) + +##### Recommendation + +We recommend using `initializer` and `initializable` modifiers from Openzeppelin instead of implementing custom modifiers. + + +#### [NEW] Stream manager, treasury manager and admin represent the same account in `StakingHandlers` + +##### Description + +In the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function in the `StakingHandlers` contract multiple roles are assigned to the same `admin` address. + +##### Recommendation +We recommend to transfer treasury role after the deployment and the staking setting. Admin and manager of the initial `stream` should be two different roles. + + +#### [NEW] Revert message strings are too long + +##### Description + +- [`VMainToken.sol#L65-L68`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65-L68) +- [`MultiSigWallet#L30`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L30) +- [`MultiSigWallet.sol#L55`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L55) +- [`MultiSigWallet.sol#L77`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L77) + +After the revert message string is split into 32-byte sized chunks and stored in `memory` using `mstore`, the `memory` offsets are given to `revert(offset, length)`. For chunks shorter than 32 bytes, and for low `--optimize-runs` values (usually even the default value of `200`), instead of using `push32(val)` (where `val` is the 32 byte hexadecimal representation of the string with zero padding on the least significant bits) the Solidity compiler replaces it by `shl(value, short-value)`, where `short-value` does not have any zero padding. This saves the total amount of bytes in the deploy code and therefore saves deploy time cost, at the expense of extra 6 gas consumption during runtime. +This means that shorter revert strings saves deploy time costs of the contract. Note that this is not relevant for high values of `--optimize-runs` since `push32` value will not be replaced by a `shl(value, short-value)` equivalent by the Solidity compiler. + +Going back, each 32 byte chunk of the string requires an extra `mstore`. That is, additional cost for `mstore`, `memory` expansion costs, as well as stack operations. Note that this runtime cost is only relevant when the revert condition is met. + +Overall, shorter revert strings can save deploy time as well as runtime costs. + +##### Recommendation + +We recommend making revert strings shorter. +Note that if your contracts already allow Solidity `0.8.4` and above, then consider using [custom errors](https://blog.soliditylang.org/2021/04/21/custom-errors). They provide more gas efficiency and also allow developers to describe the errors in detail using [NatSpec](https://docs.soliditylang.org/en/latest/natspec-format.html). The main disadvantage of this approach is that some tooling may not have proper support for it yet. + + +#### [NEW] Unnecessary reads from storage + +##### Description + +In the next lines using `MLOAD` and `MSTORE` to cache the variable in `memory` saves more gas than `SLOAD`, since they use only 3 gas, instead of the initial 100: + +- [`MultiSigWallet.sol#L138`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L138) +- [`StakingHandler.sol#L191`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L191) +- [`StakingHandler.sol#L200`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L200) +- [`StakingHandler.sol#L210`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L210) +- [`StakingHandler.sol#L237`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L237) +- [`StakingHandler.sol#L244`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L244) + + +##### Recommendation + +We recommend caching this storage variable in `memory` to reduce unnecessary reads from storage and save more gas. + + +#### [NEW] Misleading check `(scheduleTimeLength > 0)` in the `RewardsCalculator` + +##### Description + +In the function [`_getStartEndScheduleIndex`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L94) in the contract `RewardsCalculator` there is the following condition: +```solidity +require(scheduleTimeLength > 0, "bad schedules"); +``` + +This condition allows `scheduleTimeLength` value to be set to 1. This can lead to [underflow](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L105) and [incorrect operation of cycles](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L98) further down the code. + +##### Recommendation + +We recommend changing it to +```solidity +require(scheduleTimeLength >= 2, "bad schedules"); +``` +or completely remove this check, since this condition is already checked in `validateStreamParameters()` when the stream is created. + +## Conclusion + +The following table contains the total number of issues that were found during audit: + +[FINDINGS] + +Current audit revealed 75 issues of varying degrees of importance. For each founded issue the Contractor's team made recommendations on effective solving. \ No newline at end of file diff --git a/contracts/common/Address.sol b/contracts/common/Address.sol index 94610d5..c05ea9d 100644 --- a/contracts/common/Address.sol +++ b/contracts/common/Address.sol @@ -175,6 +175,14 @@ library Address { return verifyCallResult(success, returndata, errorMessage); } + function getExtCodeHash(address target) internal view returns (bytes32) { + bytes32 codeHash; + assembly { + codeHash := extcodehash(target) + } + return codeHash; + } + /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 54afae0..3dc486c 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -24,13 +24,15 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { event ConfirmProposal(address indexed signer, uint indexed proposalId); event RevokeConfirmation(address indexed signer, uint indexed proposalId); event ExecuteProposal(address indexed signer, uint indexed proposalId); + event MultiSigUpdated(address indexed newMultiSig, address oldMultiSig); bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); - + //AuditFix There is no validation for `maxTargets` when executing in `Governor` - ASK THIS, to make it constant or as argument + uint256 public constant MAX_TARGETS = uint256(10); string private _name; uint256[] private proposalIds; - + address private multiSig; mapping(uint256 => ProposalCore) internal _proposals; @@ -80,6 +82,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { bytes32 descriptionHash ) public payable virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); + requireConfirmed(proposalId); ProposalState status = state(proposalId); require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); @@ -152,7 +155,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { require(targets.length == values.length, "Governor: invalid proposal length"); require(targets.length == calldatas.length, "Governor: invalid proposal length"); require(targets.length > 0, "Governor: empty proposal"); - + require(targets.length <= MAX_TARGETS,"Governor: invalid proposal length"); ProposalCore storage proposal = _proposals[proposalId]; require(proposal.voteStart.isUnset(), "Governor: proposal already exists"); @@ -177,13 +180,19 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { } function revokeConfirmation(uint _proposalId) public onlyMultiSig notExecuted(_proposalId) { - require(isConfirmed[_proposalId], "proposal not confirmed"); + requireConfirmed(_proposalId); isConfirmed[_proposalId] = false; emit RevokeConfirmation(msg.sender, _proposalId); } + //AuditFix There is no possibility to update `multisig` in `Governor + function updateMultiSig(address newMultiSig) public onlyMultiSig { + require(newMultiSig != address(0), "updateMultiSig: newMultiSig cant be set to zero address"); + emit MultiSigUpdated(newMultiSig, multiSig); + multiSig = newMultiSig; + } function getProposals(uint _numIndexes) public view override returns (string[] memory, string[] memory, string[] memory) { uint len = proposalIds.length; @@ -199,6 +208,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { return _getProposals1(_numIndexes); } + function _getProposals1(uint _numIndexes) internal view returns (string[] memory, string[] memory, string[] memory) { string[] memory _statusses = new string[](_numIndexes); string[] memory _descriptionsArray = new string[](_numIndexes); @@ -458,6 +468,10 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { return (_proposalIds, _descriptionsArray, _statusses); } + function requireConfirmed(uint _proposalId) internal view { + require(isConfirmed[_proposalId], "proposal not confirmed"); + } + function _executor() internal view virtual returns (address) { return address(this); } diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index 32abe5a..16f5ad3 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -55,6 +55,8 @@ contract TimelockController is AccessControl, Initializable, ITimelockController _setupRole(TIMELOCK_ADMIN_ROLE, admin); _setupRole(TIMELOCK_ADMIN_ROLE, address(this)); + _grantRole(DEFAULT_ADMIN_ROLE, admin); + for (uint256 i = 0; i < proposers.length; ++i) { _setupRole(PROPOSER_ROLE, proposers[i]); _setupRole(CANCELLER_ROLE, proposers[i]); diff --git a/contracts/dao/governance/extensions/GovernorSettings.sol b/contracts/dao/governance/extensions/GovernorSettings.sol index 4114a09..ce5f628 100644 --- a/contracts/dao/governance/extensions/GovernorSettings.sol +++ b/contracts/dao/governance/extensions/GovernorSettings.sol @@ -58,6 +58,7 @@ abstract contract GovernorSettings is Governor { function _setProposalThreshold(uint256 newProposalThreshold) internal virtual { emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold); + require(newProposalThreshold > 0,"_setProposalThreshold: Threshold for proposal cant be zero"); _proposalThreshold = newProposalThreshold; } } diff --git a/contracts/dao/governance/extensions/GovernorTimelockControl.sol b/contracts/dao/governance/extensions/GovernorTimelockControl.sol index 765ec08..528d285 100644 --- a/contracts/dao/governance/extensions/GovernorTimelockControl.sol +++ b/contracts/dao/governance/extensions/GovernorTimelockControl.sol @@ -109,6 +109,7 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { } function _updateTimelock(TimelockController newTimelock) private { + require(address(newTimelock) != address(0), "updateTimelock: newTimelock address cannot be zero address"); emit TimelockChange(address(_timelock), address(newTimelock)); _timelock = newTimelock; } diff --git a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol b/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol index a1a434e..6de97fe 100644 --- a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol +++ b/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol @@ -9,7 +9,7 @@ import "./GovernorVotes.sol"; abstract contract GovernorVotesQuorumFraction is GovernorVotes { uint256 private _quorumNumerator; - + uint256 public constant MINIMUM_QUORUM_NUMERATOR = uint256(4); event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); /** @@ -54,7 +54,7 @@ abstract contract GovernorVotesQuorumFraction is GovernorVotes { function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual { require(newQuorumNumerator <= quorumDenominator(), "GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator"); - + require(newQuorumNumerator >= MINIMUM_QUORUM_NUMERATOR, "GovernorVotesQuorumFraction: quorumNumerator less than Minimum"); uint256 oldQuorumNumerator = _quorumNumerator; _quorumNumerator = newQuorumNumerator; diff --git a/contracts/dao/staking/StakingStorage.sol b/contracts/dao/staking/StakingStorage.sol index fafa54e..90949dc 100644 --- a/contracts/dao/staking/StakingStorage.sol +++ b/contracts/dao/staking/StakingStorage.sol @@ -16,6 +16,7 @@ contract StakingStorage { uint64 internal constant ONE_MONTH = 2629746; uint64 internal constant ONE_YEAR = 31536000; //MAX_LOCK: It is a constant. One WEEK Added as a tolerance. + uint256 public maxLockPeriod; ///@notice Checks if the staking is initialized @@ -51,4 +52,5 @@ contract StakingStorage { ///Mapping (user => LockedBalance) to keep locking information for each user mapping(address => LockedBalance[]) internal locks; + mapping(uint256 => uint256) public streamTotalUserPendings; } diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index c77c8ff..934323a 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -60,13 +60,4 @@ interface IStakingHandler { function withdrawPenalty(address penaltyReceiver) external; function updateVault(address _vault) external; - - function updateConfig( - Weight calldata _weight, - address _voteToken, - address _rewardsCalculator, - VoteCoefficient calldata _voteCoef, - uint256 _maxLockPeriod, - uint256 _maxLockPositions - ) external; } diff --git a/contracts/dao/staking/interfaces/IStakingStorage.sol b/contracts/dao/staking/interfaces/IStakingStorage.sol index bb91f91..173facd 100644 --- a/contracts/dao/staking/interfaces/IStakingStorage.sol +++ b/contracts/dao/staking/interfaces/IStakingStorage.sol @@ -15,4 +15,6 @@ interface IStakingStorage { function totalAmountOfStakedToken() external view returns (uint256); function totalPenaltyBalance() external view returns (uint256); + + function streamTotalUserPendings(uint256 streamId) external view returns (uint256); } diff --git a/contracts/dao/staking/packages/RewardsInternals.sol b/contracts/dao/staking/packages/RewardsInternals.sol index 65c39ae..650702e 100644 --- a/contracts/dao/staking/packages/RewardsInternals.sol +++ b/contracts/dao/staking/packages/RewardsInternals.sol @@ -26,6 +26,7 @@ contract RewardsInternals is StakingStorage, IStakingEvents { if (reward == 0) return; // All rewards claimed or stream schedule didn't start userAccount.pendings[streamId] += reward; + streamTotalUserPendings[streamId] += reward; userAccount.rpsDuringLastClaimForLock[lockId][streamId] = streams[streamId].rps; userAccount.releaseTime[streamId] = block.timestamp + streams[streamId].tau; // If the stream is blacklisted, remaining unclaimed rewards will be transfered out. diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index ab8fc34..c7198eb 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -10,12 +10,12 @@ import "../interfaces/IStakingHandler.sol"; import "../vault/interfaces/IVault.sol"; import "../../../common/security/ReentrancyGuard.sol"; import "../../../common/security/AdminPausable.sol"; - +import "../../../common/SafeERC20.sol"; // solhint-disable not-rely-on-time contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, ReentrancyGuard, AdminPausable { + using SafeERC20 for IERC20; bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); - /** * @dev initialize the contract and deploys the first stream of rewards * @dev initializable only once due to stakingInitialised flag @@ -148,8 +148,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R require(stream.schedule.reward[0] == stream.rewardDepositAmount, "bad start point"); emit StreamCreated(streamId, stream.owner, stream.rewardToken, rewardTokenAmount); - - IERC20(stream.rewardToken).transferFrom(msg.sender, address(vault), rewardTokenAmount); + IVault(vault).deposit(msg.sender, stream.rewardToken, rewardTokenAmount); } function cancelStreamProposal(uint256 streamId) public override onlyRole(STREAM_MANAGER_ROLE) { @@ -162,6 +161,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R function removeStream(uint256 streamId, address streamFundReceiver) public override onlyRole(STREAM_MANAGER_ROLE) { require(streamId != 0, "Stream 0"); + require(streamTotalUserPendings[streamId] == 0, "stream not withdrawn"); Stream storage stream = streams[streamId]; require(stream.status == StreamStatus.ACTIVE, "No Stream"); stream.status = StreamStatus.INACTIVE; @@ -193,6 +193,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R _updateStreamRPS(); uint256 stakeValue = lock.amountOfToken; _unlock(stakeValue, stakeValue, lockId, msg.sender); + prohibitedEarlyWithdraw[msg.sender][lockId] = false; } function unlockPartially(uint256 lockId, uint256 amount) public override pausable(1) { @@ -211,6 +212,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R require(lock.end > block.timestamp, "lock opened"); _updateStreamRPS(); _earlyUnlock(lockId, msg.sender); + prohibitedEarlyWithdraw[msg.sender][lockId] = false; } function claimRewards(uint256 streamId, uint256 lockId) public override pausable(1) { @@ -237,35 +239,23 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R User storage userAccount = users[msg.sender]; require(userAccount.pendings[streamId] != 0, "no pendings"); require(block.timestamp > userAccount.releaseTime[streamId], "not released"); + require(streams[streamId].status == StreamStatus.ACTIVE,"stream not active"); _withdraw(streamId); } function withdrawAllStreams() public override pausable(1) { User storage userAccount = users[msg.sender]; for (uint256 i = 0; i < streams.length; i++) { - if (userAccount.pendings[i] != 0 && block.timestamp > userAccount.releaseTime[i]) { + if ( + userAccount.pendings[i] != 0 && + block.timestamp > userAccount.releaseTime[i] && + streams[i].status == StreamStatus.ACTIVE) + { _withdraw(i); } } } - function updateConfig( - Weight memory _weight, - address _voteToken, - address _rewardsCalculator, - VoteCoefficient memory _voteCoef, - uint256 _maxLockPeriod, - uint256 _maxLockPositions - ) public override onlyRole(DEFAULT_ADMIN_ROLE) { - weight = _weight; - voteToken = _voteToken; - rewardsCalculator = _rewardsCalculator; - voteShareCoef = _voteCoef.voteShareCoef; - voteLockCoef = _voteCoef.voteLockCoef; - maxLockPeriod = _maxLockPeriod; - maxLockPositions = _maxLockPositions; - } - function updateVault(address _vault) public override onlyRole(DEFAULT_ADMIN_ROLE) { // enforce pausing this contract before updating the address. // This mitigates the risk of future invalid reward claims @@ -286,7 +276,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R require(lockPeriod <= maxLockPeriod, "max lock period"); _updateStreamRPS(); _lock(account, amount, lockPeriod); - IERC20(mainToken).transferFrom(msg.sender, address(vault), amount); + IERC20(mainToken).safeTransferFrom(msg.sender, address(vault), amount); } function _verifyUnlock(uint256 lockId) internal view { diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 9713fee..090aeef 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -29,6 +29,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { require(_weight.maxWeightShares > _weight.minWeightShares, "bad share"); require(_weight.maxWeightPenalty > _weight.minWeightPenalty, "bad penalty"); + require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "Wrong penalty weight"); mainToken = _mainToken; voteToken = _voteToken; weight = _weight; @@ -120,7 +121,9 @@ contract StakingInternals is StakingStorage, RewardsInternals { uint256 streamsLength = streams.length; for (uint256 i = 0; i < streamsLength; i++) { - userAccount.rpsDuringLastClaimForLock[lockId][i] = streams[i].rps; + if(streams[i].status == StreamStatus.ACTIVE){ + userAccount.rpsDuringLastClaimForLock[lockId][i] = streams[i].rps; + } } emit Staked(account, amount, weightedAmountOfSharesPerStream, nVoteToken, lockId, lock.end); } @@ -138,7 +141,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { userAccount.pendings[MAIN_STREAM] += amount; userAccount.releaseTime[MAIN_STREAM] = block.timestamp + streams[MAIN_STREAM].tau; - + streamTotalUserPendings[MAIN_STREAM] += amount; ///@notice: Only update the lock if it has remaining stake if (amountToRestake > 0) { _restakeThePosition(amountToRestake, lockId, updateLock, userAccount); @@ -161,7 +164,9 @@ contract StakingInternals is StakingStorage, RewardsInternals { uint256 streamsLength = streams.length; for (uint256 i = 0; i < streamsLength; i++) { // The new shares should not claim old rewards - userAccount.rpsDuringLastClaimForLock[lockId][i] = streams[i].rps; + if(streams[i].status == StreamStatus.ACTIVE){ + userAccount.rpsDuringLastClaimForLock[lockId][i] = streams[i].rps; + } } } @@ -183,6 +188,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { uint256 penalty = (weighingCoef * amount) / 100000; User storage userAccount = users[account]; userAccount.pendings[MAIN_STREAM] -= penalty; + streamTotalUserPendings[MAIN_STREAM] -= penalty; totalPenaltyBalance += penalty; } @@ -206,6 +212,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { User storage userAccount = users[msg.sender]; uint256 pendingAmount = userAccount.pendings[streamId]; userAccount.pendings[streamId] = 0; + streamTotalUserPendings[streamId] -= pendingAmount; emit Released(streamId, msg.sender, pendingAmount); IVault(vault).payRewards(msg.sender, streams[streamId].rewardToken, pendingAmount); } @@ -227,7 +234,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { if (timestamp >= slopeEnd) return shares * weight.minWeightShares; return shares * - weight.maxWeightShares + + weight.minWeightShares + (shares * (weight.maxWeightShares - weight.minWeightShares) * (slopeEnd - timestamp)) / (slopeEnd - slopeStart); } diff --git a/contracts/dao/staking/vault/interfaces/IVault.sol b/contracts/dao/staking/vault/interfaces/IVault.sol index 2efdc38..8b2d4bb 100644 --- a/contracts/dao/staking/vault/interfaces/IVault.sol +++ b/contracts/dao/staking/vault/interfaces/IVault.sol @@ -2,9 +2,9 @@ pragma solidity 0.8.13; interface IVault { - function initVault(address[] calldata supportedTokens) external; + function initVault(address _admin,address[] calldata supportedTokens) external; - function initAdminAndOperator(address _admin, address _rewardsOperator) external; + function addRewardsOperator(address _rewardsOperator) external; function addSupportedToken(address _token) external; @@ -13,4 +13,5 @@ interface IVault { function payRewards(address _user, address _token, uint256 _deposit) external; function isSupportedToken(address token) external view returns (bool); + function deposit(address _user, address _token, uint256 _amount) external; } diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index b5a8bb2..c5bae0c 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -7,31 +7,39 @@ import "../interfaces/IVault.sol"; import "../interfaces/IVaultEvents.sol"; import "../../../tokens/ERC20/IERC20.sol"; import "../../../../common/security/AdminPausable.sol"; - +import "../../../../common/SafeERC20.sol"; // solhint-disable not-rely-on-time contract VaultPackage is IVault, IVaultEvents, AdminPausable { + using SafeERC20 for IERC20; bool private vaultInitialized; bytes32 public constant REWARDS_OPERATOR_ROLE = keccak256("REWARDS_OPERATOR_ROLE"); - + mapping(address => uint256) public deposited; mapping(address => bool) public override isSupportedToken; - function initVault(address[] calldata supportedTokens) external override { + + function initVault(address _admin,address[] calldata supportedTokens) external override { require(!vaultInitialized, "Vault: Already Initialized"); vaultInitialized = true; for (uint i = 0; i < supportedTokens.length; i++) { _addSupportedToken(supportedTokens[i]); } + pausableInit(0, _admin); } - function initAdminAndOperator(address _admin, address _rewardsOperator) external override { - pausableInit(0, _admin); + function addRewardsOperator(address _rewardsOperator) external override onlyRole(DEFAULT_ADMIN_ROLE){ _grantRole(REWARDS_OPERATOR_ROLE, _rewardsOperator); } - function payRewards(address _user, address _token, uint256 _amount) external override { + function payRewards(address _user, address _token, uint256 _amount) external override pausable(1){ + require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "payRewards: No role"); + require(isSupportedToken[_token], "Unsupported token"); + IERC20(_token).safeTransfer(_user,_amount); + } + + function deposit(address _user, address _token, uint256 _amount) external override pausable(1) { require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "payRewards: No role"); require(isSupportedToken[_token], "Unsupported token"); - IERC20(_token).transfer(_user, _amount); + IERC20(_token).safeTransferFrom(_user, address(this),_amount); } /// @notice adds token as a supproted rewards token by Vault diff --git a/contracts/dao/tokens/IVMainToken.sol b/contracts/dao/tokens/IVMainToken.sol index b7917c6..b1b3d5d 100644 --- a/contracts/dao/tokens/IVMainToken.sol +++ b/contracts/dao/tokens/IVMainToken.sol @@ -21,4 +21,6 @@ interface IVMainToken { function mint(address to, uint256 amount) external; function burn(address account, uint256 amount) external; + function grantMinterRole(address _minter) external; + function revokeMinterRole(address _minter) external; } diff --git a/contracts/dao/tokens/VMainToken.sol b/contracts/dao/tokens/VMainToken.sol index 8992818..7a8abd1 100644 --- a/contracts/dao/tokens/VMainToken.sol +++ b/contracts/dao/tokens/VMainToken.sol @@ -12,7 +12,7 @@ import "@openzeppelin/contracts/proxy/utils/Initializable.sol"; contract VMainToken is IVMainToken, Pausable, AccessControl, Initializable, ERC20Votes { bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); - bytes32 public constant WHITELISTER_ROLE = keccak256("MINTER_ROLE"); + bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); bool private initialized; // Mapping to keep track of who is allowed to transfer voting tokens mapping(address => bool) public isWhiteListed; @@ -24,6 +24,7 @@ contract VMainToken is IVMainToken, Pausable, AccessControl, Initializable, ERC2 function initToken(address _admin, address _minter) public override initializer onlyRole(DEFAULT_ADMIN_ROLE) { require(!initialized, "already init"); initialized = true; + require(_admin != msg.sender, "initToken: Admin should be different than msg.sender"); _grantRole(DEFAULT_ADMIN_ROLE, _admin); _grantRole(PAUSER_ROLE, _admin); _grantRole(MINTER_ROLE, _minter); @@ -44,6 +45,16 @@ contract VMainToken is IVMainToken, Pausable, AccessControl, Initializable, ERC2 isWhiteListed[_toRemove] = false; emit MemberRemovedFromWhitelist(_toRemove); } + //AuditFix When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update + function grantMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)){ + _grantRole(MINTER_ROLE, _minter); + addToWhitelist(_minter); + } + + function revokeMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)){ + _grantRole(MINTER_ROLE, _minter); + removeFromWhitelist(_minter); + } function pause() public override onlyRole(PAUSER_ROLE) { _pause(); diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index a5cc560..3766636 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -4,26 +4,35 @@ pragma solidity 0.8.13; import "./interfaces/IMultiSigWallet.sol"; +import "../../common/Address.sol"; contract MultiSigWallet is IMultiSigWallet { + using Address for address; + struct Transaction { address to; - uint value; - bytes data; bool executed; + bytes data; + uint value; uint numConfirmations; + uint expireTimestamp; } + error TransactionRevered(bytes data); + uint public constant MAX_OWNER_COUNT = 50; address[] public owners; address public governor; uint public numConfirmationsRequired; + uint public lastDisabledTransactionIndex; mapping(address => bool) public isOwner; mapping(uint => mapping(address => bool)) public isConfirmed; + mapping(address => bytes32) internal whitelistedBytesCode; + Transaction[] public transactions; modifier onlyOwnerOrGov() { @@ -46,23 +55,26 @@ contract MultiSigWallet is IMultiSigWallet { _; } - modifier ownerDoesNotExist(address owner) { - require(!isOwner[owner], "MultiSig: Owner already exists"); + modifier notDisabled(uint _txIndex) { + require(_txIndex >= lastDisabledTransactionIndex, "MultiSig: old txs has been disabled"); _; } - modifier onlyWallet() { - require(msg.sender == address(this), "MultiSig: Only this wallet can use this funciton"); + modifier notExpired(uint _txIndex) { + require(transactions[_txIndex].expireTimestamp >= block.timestamp || transactions[_txIndex].expireTimestamp == 0, "MultiSig: tx expired"); _; } - modifier notNull(address _address) { - require(_address != address(0), "MultiSig: _address == 0"); + modifier onlyWallet() { + require(msg.sender == address(this), "MultiSig: Only this wallet can use this funciton"); _; } modifier validRequirement(uint ownerCount, uint _required) { - require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, "MultiSig: Invalid requirement"); + require( + ownerCount > 0 && ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && ownerCount > 1 ? _required > 1 : _required > 0, + "MultiSig: Invalid requirement" + ); _; } @@ -71,8 +83,28 @@ contract MultiSigWallet is IMultiSigWallet { _; } + modifier validateSubmitTxInputs( + address _to, + uint _value, + bytes memory _data, + uint _expireTimestamp + ) { + require(_expireTimestamp >= block.timestamp || _expireTimestamp == 0, "already expired"); + + if (_to.isContract()) { + require(_data.length > 0, "no calldata for contract call"); + } else { + require(_data.length == 0 && _value > 0, "calldata for EOA call or 0 value"); + } + + require(address(this).balance >= _value, "not enough balance"); + + _; + } + constructor(address[] memory _owners, uint _numConfirmationsRequired, address _governor) { governor = _governor; + require(_owners.length <= MAX_OWNER_COUNT, "owners limit reached"); require(_owners.length > 0, "owners required"); require(_numConfirmationsRequired > 0 && _numConfirmationsRequired <= _owners.length, "invalid number of required confirmations"); @@ -101,16 +133,28 @@ contract MultiSigWallet is IMultiSigWallet { break; } owners.pop(); + if (numConfirmationsRequired > owners.length) changeRequirement(owners.length); + + lastDisabledTransactionIndex = getTransactionCount(); + emit OwnerRemoval(owner); } - function addOwner( - address owner - ) public override onlyWallet ownerDoesNotExist(owner) notNull(owner) validRequirement(owners.length + 1, numConfirmationsRequired) { - isOwner[owner] = true; - owners.push(owner); - emit OwnerAddition(owner); + function addOwners( + address[] memory _owners + ) public override onlyWallet validRequirement(owners.length + _owners.length, numConfirmationsRequired + _owners.length) { + for (uint i = 0; i < _owners.length; i++) { + address owner = _owners[i]; + require(owner != address(0), "MultiSig: owner address == 0"); + _requireNewOwner(owner); + + isOwner[owner] = true; + owners.push(owner); + emit OwnerAddition(owner); + } + + changeRequirement(numConfirmationsRequired + _owners.length); } function changeRequirement(uint _required) public override onlyWallet validRequirement(owners.length, _required) { @@ -118,36 +162,60 @@ contract MultiSigWallet is IMultiSigWallet { emit RequirementChange(_required); } - function submitTransaction(address _to, uint _value, bytes memory _data) public override onlyOwnerOrGov { + function submitTransaction( + address _to, + uint _value, + bytes memory _data, + uint _expireTimestamp + ) public override onlyOwnerOrGov validateSubmitTxInputs(_to, _value, _data, _expireTimestamp) { uint txIndex = transactions.length; - transactions.push(Transaction({ to: _to, value: _value, data: _data, executed: false, numConfirmations: 0 })); + transactions.push( + Transaction({ to: _to, value: _value, data: _data, executed: false, numConfirmations: 0, expireTimestamp: _expireTimestamp }) + ); + + whitelistedBytesCode[_to] = _to.getExtCodeHash(); emit SubmitTransaction(txIndex, msg.sender, _to, _value, _data); } - function confirmTransaction(uint _txIndex) public override onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) notConfirmed(_txIndex) { + function confirmTransaction( + uint _txIndex + ) public override onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) notConfirmed(_txIndex) notDisabled(_txIndex) notExpired(_txIndex) { Transaction storage transaction = transactions[_txIndex]; + + _requireTargetCodeNotChanged(transaction.to); + transaction.numConfirmations += 1; isConfirmed[_txIndex][msg.sender] = true; emit ConfirmTransaction(msg.sender, _txIndex); } - function executeTransaction(uint _txIndex) public override onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) { + function executeTransaction( + uint _txIndex + ) public override onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) notDisabled(_txIndex) notExpired(_txIndex) { Transaction storage transaction = transactions[_txIndex]; + _requireTargetCodeNotChanged(transaction.to); + require(transaction.numConfirmations >= numConfirmationsRequired, "cannot execute tx"); transaction.executed = true; - (bool success, ) = transaction.to.call{ value: transaction.value }(transaction.data); - require(success, "tx failed"); + (bool success, bytes memory data) = transaction.to.call{ value: transaction.value }(transaction.data); + if (success) { + emit ExecuteTransaction(msg.sender, _txIndex); + } else { + revert TransactionRevered(data); + } emit ExecuteTransaction(msg.sender, _txIndex); } - function revokeConfirmation(uint _txIndex) public override onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) { + function revokeConfirmation( + uint _txIndex + ) public override onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) notDisabled(_txIndex) notExpired(_txIndex) { Transaction storage transaction = transactions[_txIndex]; require(isConfirmed[_txIndex][msg.sender], "tx not confirmed"); @@ -168,9 +236,17 @@ contract MultiSigWallet is IMultiSigWallet { function getTransaction( uint _txIndex - ) public view override returns (address to, uint value, bytes memory data, bool executed, uint numConfirmations) { - Transaction storage transaction = transactions[_txIndex]; + ) public view override returns (address to, uint value, bytes memory data, bool executed, uint numConfirmations, uint expireTimestamp) { + Transaction memory transaction = transactions[_txIndex]; + + return (transaction.to, transaction.value, transaction.data, transaction.executed, transaction.numConfirmations, transaction.expireTimestamp); + } + + function _requireNewOwner(address owner) internal view { + require(!isOwner[owner], "MultiSig: Owner already exists"); + } - return (transaction.to, transaction.value, transaction.data, transaction.executed, transaction.numConfirmations); + function _requireTargetCodeNotChanged(address target) internal view { + require(whitelistedBytesCode[target] == target.getExtCodeHash(), "target code changed"); } } diff --git a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol index 4e37427..10b0186 100644 --- a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol +++ b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol @@ -17,11 +17,11 @@ interface IMultiSigWallet { function removeOwner(address owner) external; - function addOwner(address owner) external; + function addOwners(address[] calldata _owners) external; function changeRequirement(uint _required) external; - function submitTransaction(address _to, uint _value, bytes memory _data) external; + function submitTransaction(address _to, uint _value, bytes memory _data, uint _expireTimestamp) external; function confirmTransaction(uint _txIndex) external; @@ -33,5 +33,7 @@ interface IMultiSigWallet { function getTransactionCount() external returns (uint); - function getTransaction(uint _txIndex) external returns (address to, uint value, bytes memory data, bool executed, uint numConfirmations); + function getTransaction( + uint _txIndex + ) external returns (address to, uint value, bytes memory data, bool executed, uint numConfirmations, uint expireTimestamp); } diff --git a/coralX-config.js b/coralX-config.js index a95e8d9..2cee8e5 100644 --- a/coralX-config.js +++ b/coralX-config.js @@ -36,7 +36,7 @@ module.exports = { optimizer: { enabled: true, details: { yul: false }, - runs: 400, + runs: 200, }, evmVersion: 'istanbul', }, diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index c4ace07..5a04c47 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -160,7 +160,7 @@ module.exports = async function(deployer) { await deployer.deploy(StakingProxyAdmin, {gas:8000000}); await deployer.deploy(StakingProxy, StakingPackage.address, StakingProxyAdmin.address, toInitialize, {gas:8000000}); - await vaultService.initAdminAndOperator(MultiSigWallet.address,StakingProxy.address) + await vaultService.initRewardsOperator(StakingProxy.address) } catch(error) { console.log(error) } diff --git a/scripts/migrations/prod/2_add_vault_operator.js b/scripts/migrations/prod/2_add_vault_operator.js new file mode 100644 index 0000000..cd2aea8 --- /dev/null +++ b/scripts/migrations/prod/2_add_vault_operator.js @@ -0,0 +1,43 @@ +const eventsHelper = require("../../tests/helpers/eventsHelper"); + +const IVault = artifacts.require('./dao/staking/vault/interfaces/IVault.sol'); +const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); +const IERC20 = artifacts.require("./dao/tokens/ERC20/IERC20.sol"); + +const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); +const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); +const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; +const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; + +const T_TO_TRANSFER = web3.utils.toWei('20000', 'ether'); +const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') +const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') + +const _encodeTransferFunction = (_account, _amount) => { + let toRet = web3.eth.abi.encodeFunctionCall({ + name: 'addRewardsOperator', + type: 'function', + inputs: [{ + type: 'address', + name: '_rewardsOperator' + } + ] + }, [_account]); + + return toRet; +} + +module.exports = async function(deployer) { + const multiSigWallet = await IMultiSigWallet.at(MultiSigWallet.address) + let result = await multiSigWallet.submitTransaction( + VaultProxy.address, + EMPTY_BYTES, + _encodeTransferFunction(StakingProxy.address), + 0, + {gas: 8000000} + ); + + let txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); + await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); +} diff --git a/scripts/migrations/prod/5_setup_council_stakes.js b/scripts/migrations/prod/5_setup_council_stakes.js index 342451c..c23da86 100644 --- a/scripts/migrations/prod/5_setup_council_stakes.js +++ b/scripts/migrations/prod/5_setup_council_stakes.js @@ -46,6 +46,7 @@ module.exports = async function(deployer) { MainToken.address, EMPTY_BYTES, _encodeTransferFunction(accounts[0], T_TO_TRANSFER), + 0, {gas: 8000000} ); let txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; diff --git a/scripts/migrations/prod/6_setup_vault_tokens.js b/scripts/migrations/prod/6_setup_vault_tokens.js index 43edf83..5561d68 100644 --- a/scripts/migrations/prod/6_setup_vault_tokens.js +++ b/scripts/migrations/prod/6_setup_vault_tokens.js @@ -36,6 +36,7 @@ module.exports = async function(deployer) { MainToken.address, EMPTY_BYTES, _encodeTransferFunction(vaultService.address, T_TO_TRANSFER), + 0, {gas: 8000000} ); diff --git a/scripts/migrations/prod/7_setup_multisig.js b/scripts/migrations/prod/7_setup_multisig.js index 64a6b6b..d182e26 100644 --- a/scripts/migrations/prod/7_setup_multisig.js +++ b/scripts/migrations/prod/7_setup_multisig.js @@ -11,28 +11,15 @@ const COUNCIL_2 = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; const NEW_MULTISIG_REQUIREMENT = 3; -const _encodeAddOwnerFunction = (_account) => { +const _encodeAddOwnersFunction = (_accounts) => { let toRet = web3.eth.abi.encodeFunctionCall({ - name: 'addOwner', + name: 'addOwners', type: 'function', inputs: [{ - type: 'address', - name: 'owner' + type: 'address[]', + name: '_owners' }] - }, [_account]); - - return toRet; -} - -const _encodeChangeRequirementFunction = (number) => { - let toRet = web3.eth.abi.encodeFunctionCall({ - name: 'changeRequirement', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_required' - }] - }, [number]); + }, [_accounts]); return toRet; } @@ -43,31 +30,8 @@ module.exports = async function(deployer) { let result = await multiSigWallet.submitTransaction( multiSigWallet.address, EMPTY_BYTES, - _encodeAddOwnerFunction(COUNCIL_1), - {gas: 8000000} - ); - - txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; - - await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); - await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); - - result = await multiSigWallet.submitTransaction( - multiSigWallet.address, - EMPTY_BYTES, - _encodeAddOwnerFunction(COUNCIL_2), - {gas: 8000000} - ); - - txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; - - await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); - await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); - - result = await multiSigWallet.submitTransaction( - multiSigWallet.address, - EMPTY_BYTES, - _encodeChangeRequirementFunction(NEW_MULTISIG_REQUIREMENT), + _encodeAddOwnersFunction([COUNCIL_1, COUNCIL_2]), + 0, {gas: 8000000} ); diff --git a/scripts/migrations/setup/2_deploy_init_vault_proxy.js b/scripts/migrations/setup/2_deploy_init_vault_proxy.js index ba09cc5..76ee9d1 100644 --- a/scripts/migrations/setup/2_deploy_init_vault_proxy.js +++ b/scripts/migrations/setup/2_deploy_init_vault_proxy.js @@ -2,6 +2,7 @@ const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); const VaultProxyAdmin = artifacts.require('./common/proxy/VaultProxyAdmin.sol'); const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') const Vault = artifacts.require('./dao/staking/vault/packages/VaultPackage.sol'); +const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); module.exports = async function(deployer) { @@ -10,11 +11,15 @@ module.exports = async function(deployer) { name: 'initVault', type: 'function', inputs: [{ - type: 'address[]', - name: 'supportedTokens' + type: 'address', + name: '_admin' + }, + { + type: 'address[]', + name: 'supportedTokens' } ] - }, [[MainToken.address]]); + }, [MultiSigWallet.address,[MainToken.address]]); await deployer.deploy(VaultProxyAdmin, {gas:8000000}); await deployer.deploy(VaultProxy, Vault.address, VaultProxyAdmin.address, toInitialize, {gas:8000000}); diff --git a/scripts/migrations/test/2_deploy_init_staking_proxy.js b/scripts/migrations/test/2_deploy_init_staking_proxy.js index c4ace07..440b26b 100644 --- a/scripts/migrations/test/2_deploy_init_staking_proxy.js +++ b/scripts/migrations/test/2_deploy_init_staking_proxy.js @@ -159,8 +159,6 @@ module.exports = async function(deployer) { await deployer.deploy(StakingProxyAdmin, {gas:8000000}); await deployer.deploy(StakingProxy, StakingPackage.address, StakingProxyAdmin.address, toInitialize, {gas:8000000}); - - await vaultService.initAdminAndOperator(MultiSigWallet.address,StakingProxy.address) } catch(error) { console.log(error) } diff --git a/scripts/migrations/test/3_add_vault_operator.js b/scripts/migrations/test/3_add_vault_operator.js new file mode 100644 index 0000000..cd2aea8 --- /dev/null +++ b/scripts/migrations/test/3_add_vault_operator.js @@ -0,0 +1,43 @@ +const eventsHelper = require("../../tests/helpers/eventsHelper"); + +const IVault = artifacts.require('./dao/staking/vault/interfaces/IVault.sol'); +const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); +const IERC20 = artifacts.require("./dao/tokens/ERC20/IERC20.sol"); + +const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); +const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); +const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; +const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; + +const T_TO_TRANSFER = web3.utils.toWei('20000', 'ether'); +const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') +const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') + +const _encodeTransferFunction = (_account, _amount) => { + let toRet = web3.eth.abi.encodeFunctionCall({ + name: 'addRewardsOperator', + type: 'function', + inputs: [{ + type: 'address', + name: '_rewardsOperator' + } + ] + }, [_account]); + + return toRet; +} + +module.exports = async function(deployer) { + const multiSigWallet = await IMultiSigWallet.at(MultiSigWallet.address) + let result = await multiSigWallet.submitTransaction( + VaultProxy.address, + EMPTY_BYTES, + _encodeTransferFunction(StakingProxy.address), + 0, + {gas: 8000000} + ); + + let txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); + await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); +} diff --git a/scripts/migrations/test/6_setup_vault_tokens.js b/scripts/migrations/test/6_setup_vault_tokens.js index 43edf83..5561d68 100644 --- a/scripts/migrations/test/6_setup_vault_tokens.js +++ b/scripts/migrations/test/6_setup_vault_tokens.js @@ -36,6 +36,7 @@ module.exports = async function(deployer) { MainToken.address, EMPTY_BYTES, _encodeTransferFunction(vaultService.address, T_TO_TRANSFER), + 0, {gas: 8000000} ); diff --git a/scripts/migrations/test/7_setup_multisig.js b/scripts/migrations/test/7_setup_multisig.js index 85d6f10..1e7e956 100644 --- a/scripts/migrations/test/7_setup_multisig.js +++ b/scripts/migrations/test/7_setup_multisig.js @@ -10,28 +10,15 @@ const COUNCIL_1 = "0xc0Ee98ac1a44B56fbe2669A3B3C006DEB6fDd0f9"; const NEW_MULTISIG_REQUIREMENT = 2; -const _encodeAddOwnerFunction = (_account) => { +const _encodeAddOwnersFunction = (_accounts) => { let toRet = web3.eth.abi.encodeFunctionCall({ - name: 'addOwner', + name: 'addOwners', type: 'function', inputs: [{ - type: 'address', - name: 'owner' + type: 'address[]', + name: '_owners' }] - }, [_account]); - - return toRet; -} - -const _encodeChangeRequirementFunction = (number) => { - let toRet = web3.eth.abi.encodeFunctionCall({ - name: 'changeRequirement', - type: 'function', - inputs: [{ - type: 'uint256', - name: '_required' - }] - }, [number]); + }, [_accounts]); return toRet; } @@ -42,19 +29,8 @@ module.exports = async function(deployer) { let result = await multiSigWallet.submitTransaction( multiSigWallet.address, EMPTY_BYTES, - _encodeAddOwnerFunction(COUNCIL_1), - {gas: 8000000} - ); - - txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; - - await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); - await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); - - result = await multiSigWallet.submitTransaction( - multiSigWallet.address, - EMPTY_BYTES, - _encodeChangeRequirementFunction(NEW_MULTISIG_REQUIREMENT), + _encodeAddOwnersFunction([COUNCIL_1]), + 0, {gas: 8000000} ); diff --git a/scripts/tests/dao/demo/staking.demo.test.js b/scripts/tests/dao/demo/staking.demo.test.js index 4bd065e..3f73c1d 100644 --- a/scripts/tests/dao/demo/staking.demo.test.js +++ b/scripts/tests/dao/demo/staking.demo.test.js @@ -258,7 +258,8 @@ describe("Staking Test and Upgrade Test", () => { const result = await multiSigWallet.submitTransaction( FTHMToken.address, EMPTY_BYTES, - _encodeTransferFunction(_account, _value), + _encodeTransferFunction(_account, _value), + 0, {"from": accounts[0]} ); txIndex4 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -284,7 +285,8 @@ describe("Staking Test and Upgrade Test", () => { const result = await multiSigWallet.submitTransaction( vaultService.address, EMPTY_BYTES, - _encodeAddSupportedTokenFunction(_token), + _encodeAddSupportedTokenFunction(_token), + 0, {"from": accounts[0]} ); const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -435,7 +437,8 @@ describe("Staking Test and Upgrade Test", () => { _encodeUpgradeFunction( _proxy, _impl - ), + ), + 0, {"from": accounts[0]} ); const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -469,7 +472,8 @@ describe("Staking Test and Upgrade Test", () => { _encodeUpgradeFunction( _proxy, _impl - ), + ), + 0, {"from": accounts[0]} ); const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -568,7 +572,8 @@ describe("Staking Test and Upgrade Test", () => { _scheduleTimes, _scheduleRewards, _tau - ), + ), + 0, {"from": accounts[0]} ); const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -597,7 +602,7 @@ describe("Staking Test and Upgrade Test", () => { console.log(".........Creating the stream proposed.........") console.log("Once create stream is called, the proposal will become live once start time is reached") const RewardProposalAmountForAStream = web3.utils.toWei('1000', 'ether'); - await streamReward2.approve(stakingService.address, RewardProposalAmountForAStream, {from:stream_rewarder_2}) + await streamReward2.approve(vaultService.address, RewardProposalAmountForAStream, {from:stream_rewarder_2}) await stakingService.createStream(streamId,RewardProposalAmountForAStream, {from: stream_rewarder_2}); }) diff --git a/scripts/tests/dao/full-flow-demo.test.js b/scripts/tests/dao/full-flow-demo.test.js index b6289fd..f4498fd 100644 --- a/scripts/tests/dao/full-flow-demo.test.js +++ b/scripts/tests/dao/full-flow-demo.test.js @@ -234,6 +234,28 @@ const _encodeProposeStreamFunction = ( return toRet; } +const _encodeRevokeFunction = ( + _role, + _account +) => { + let toRet = web3.eth.abi.encodeFunctionCall({ + name: 'revokeRole', + type: 'function', + inputs: [{ + type: 'bytes32', + name: 'role' + },{ + type: 'address', + name: 'account' + }] + }, [ + _role, + _account + ]); + + return toRet; +} + describe("DAO Demo", () => { const oneYear = 31556926; let stakingService; @@ -335,7 +357,8 @@ describe("DAO Demo", () => { const result = await multiSigWallet.submitTransaction( FTHMToken.address, EMPTY_BYTES, - _encodeTransferFunction(_account, _value), + _encodeTransferFunction(_account, _value), + 0, {"from": accounts[0]} ); txIndex4 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -354,7 +377,8 @@ describe("DAO Demo", () => { const result = await multiSigWallet.submitTransaction( vaultService.address, EMPTY_BYTES, - _encodeAddSupportedTokenFunction(_token), + _encodeAddSupportedTokenFunction(_token), + 0, {"from": accounts[0]} ); const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -471,7 +495,8 @@ describe("DAO Demo", () => { _scheduleTimes, _scheduleRewards, _tau - ), + ), + 0, {"from": accounts[0]} ); const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -497,7 +522,7 @@ describe("DAO Demo", () => { it("Should Create a stream, stream - 1", async() => { const streamId = 1 const RewardProposalAmountForAStream = web3.utils.toWei('1000', 'ether'); - await streamReward1.approve(stakingService.address, RewardProposalAmountForAStream, {from:stream_rewarder_1}); + await streamReward1.approve(vaultService.address, RewardProposalAmountForAStream, {from:stream_rewarder_1}); await stakingService.createStream(streamId,RewardProposalAmountForAStream, {from: stream_rewarder_1}); }); @@ -643,7 +668,8 @@ describe("DAO Demo", () => { const result = await multiSigWallet.submitTransaction( mainTokenGovernor.address, EMPTY_BYTES, - encodedConfirmation1, + encodedConfirmation1, + 0, {"from": accounts[0]} ); txIndex1 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -723,7 +749,9 @@ describe("DAO Demo", () => { EMPTY_BYTES, _encodeWithdrawPenaltyFunction( _penaltyReceiver - ), {"from": accounts[0]} + ), + 0, + {"from": accounts[0]} ) const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -777,8 +805,11 @@ describe("DAO Demo", () => { },{ type: 'bytes', name: '_data' + },{ + type: 'uint256', + name: '_expireTimestamp' }] - }, [FTHMTokenAddress, EMPTY_BYTES, encoded_transfer_function]); + }, [FTHMTokenAddress, EMPTY_BYTES, encoded_transfer_function, 0]); }); @@ -852,7 +883,8 @@ describe("DAO Demo", () => { const result = await multiSigWallet.submitTransaction( mainTokenGovernor.address, EMPTY_BYTES, - encodedConfirmation2, + encodedConfirmation2, + 0, {"from": accounts[0]} ); txIndex2 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -923,6 +955,7 @@ describe("DAO Demo", () => { FTHMToken.address, EMPTY_BYTES, _encodeStakeApproveFunction(approveAmount, stakingService.address), + 0, {"from": accounts[0]} ); txIndex3 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -931,6 +964,7 @@ describe("DAO Demo", () => { stakingService.address, EMPTY_BYTES, _encodeStakeFunction(amount, oneYr, comity_1, true), + 0, {"from": accounts[0]} ); txIndex5 = eventsHelper.getIndexedEventArgs(result2, SUBMIT_TRANSACTION_EVENT)[0]; @@ -939,6 +973,7 @@ describe("DAO Demo", () => { stakingService.address, EMPTY_BYTES, _encodeStakeFunction(amount, oneYr, comity_2, true), + 0, {"from": accounts[0]} ); txIndex6 = eventsHelper.getIndexedEventArgs(result_temp, SUBMIT_TRANSACTION_EVENT)[0]; @@ -1015,5 +1050,34 @@ describe("DAO Demo", () => { expect(parseInt(await FTHMToken.balanceOf(comity_2))).to.be.above(amount2); }) + it('Should revoke Proposer Role - check', async() => { + await blockchain.mineBlock(await _getTimeStamp() + 20); + const _revoke = async ( + _role, + _account + ) => { + const result = await multiSigWallet.submitTransaction( + timelockController.address, + EMPTY_BYTES, + _encodeRevokeFunction( + _role, + _account + ), + 0, + {"from": accounts[0]} + ); + const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + + await multiSigWallet.confirmTransaction(tx, {"from": accounts[0]}); + await multiSigWallet.confirmTransaction(tx, {"from": accounts[1]}); + + await multiSigWallet.executeTransaction(tx, {"from": accounts[1]}); + } + await _revoke( + proposer_role, + mainTokenGovernor.address + ) + + }) }) }) diff --git a/scripts/tests/dao/governance/multisig-treasury.test.js b/scripts/tests/dao/governance/multisig-treasury.test.js index fe79105..35956fb 100644 --- a/scripts/tests/dao/governance/multisig-treasury.test.js +++ b/scripts/tests/dao/governance/multisig-treasury.test.js @@ -63,14 +63,14 @@ describe('MultiSig Wallet', () => { }] }, [accounts[2]]); - encoded_add_owner_function = web3.eth.abi.encodeFunctionCall({ - name: 'addOwner', + encoded_add_owners_function = web3.eth.abi.encodeFunctionCall({ + name: 'addOwners', type: 'function', inputs: [{ - type: 'address', + type: 'address[]', name: 'owner' }] - }, [accounts[2]]); + }, [[accounts[2]]]); encoded_change_requirement_function = web3.eth.abi.encodeFunctionCall({ name: 'changeRequirement', @@ -79,7 +79,7 @@ describe('MultiSig Wallet', () => { type: 'uint256', name: '_required' }] - }, ['1']); + }, ['2']); }); @@ -88,7 +88,8 @@ describe('MultiSig Wallet', () => { const result = await multiSigWallet.submitTransaction( multiSigWallet.address, EMPTY_BYTES, - encoded_add_owner_function, + encoded_add_owners_function, + 0, {"from": accounts[0]} ); txIndex1 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -98,7 +99,8 @@ describe('MultiSig Wallet', () => { const result = await multiSigWallet.submitTransaction( multiSigWallet.address, EMPTY_BYTES, - encoded_remove_owner_function, + encoded_remove_owner_function, + 0, {"from": accounts[0]} ); txIndex2 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -109,7 +111,8 @@ describe('MultiSig Wallet', () => { const result = await multiSigWallet.submitTransaction( multiSigWallet.address, EMPTY_BYTES, - encoded_change_requirement_function, + encoded_change_requirement_function, + 0, {"from": accounts[0]} ); txIndex3 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -126,13 +129,13 @@ describe('MultiSig Wallet', () => { ); await shouldRevert( - multiSigWallet.addOwner(accounts[3], {"from": accounts[1]}), + multiSigWallet.addOwners([accounts[3]], {"from": accounts[1]}), errTypes.revert, errorMessage ); }); - it('Should confirm transaction 1, 2and 3, from accounts[0], the first signer', async() => { + it('Should confirm transaction 1, 2 and 3, from accounts[0], the first signer', async() => { await multiSigWallet.confirmTransaction(txIndex1, {"from": accounts[0]}); await multiSigWallet.confirmTransaction(txIndex2, {"from": accounts[0]}); await multiSigWallet.confirmTransaction(txIndex3, {"from": accounts[0]}); @@ -148,8 +151,9 @@ describe('MultiSig Wallet', () => { ); }); - it('Should confirm transactions 1 and 3, only, from accounts[1], the second signer', async() => { + it('Should confirm transactions 1, 2 and 3, only, from accounts[1], the second signer', async() => { await multiSigWallet.confirmTransaction(txIndex1, {"from": accounts[1]}); + await multiSigWallet.confirmTransaction(txIndex2, {"from": accounts[1]}); await multiSigWallet.confirmTransaction(txIndex3, {"from": accounts[1]}); }); @@ -178,11 +182,40 @@ describe('MultiSig Wallet', () => { expect((owners_after_removal[1])).to.equal(accounts[1]); }); + it('Should confirm transactions 3, only, from accounts[3], the third signer', async() => { + await multiSigWallet.confirmTransaction(txIndex3, {"from": accounts[2]}); + }); + + it('Revoke confirmation for tx 3 and expect transaction to fail when execution is tried, then reconfirm', async() => { + + await multiSigWallet.revokeConfirmation(txIndex3, {from: accounts[1]}); + + let errorMessage = "cannot execute tx"; + + await shouldRevert( + multiSigWallet.executeTransaction(txIndex3, {from: accounts[1]}), + errTypes.revert, + errorMessage + ); + + await multiSigWallet.confirmTransaction(txIndex3, {"from": accounts[1]}); + }); + + it('Fail xecute the transaction to remove third signer because min number of confirmations not reached', async() => { + let errorMessage = "cannot execute tx"; + + await shouldRevert( + multiSigWallet.executeTransaction(txIndex2, {from: accounts[0]}), + errTypes.revert, + errorMessage + ); + }); + it('Execute the transaction to change the minimum number of required confirmations to execute a proposal', async() => { await multiSigWallet.executeTransaction(txIndex3, {"from": accounts[0]}); }); - it('Execute the transaction to REMOVE an owner, even though it was only signed by one account', async() => { + it('Execute the transaction to REMOVE an owner, even though it was only signed by two account', async() => { await multiSigWallet.executeTransaction(txIndex2, {"from": accounts[0]}); owners_after_addition = await multiSigWallet.getOwners(); @@ -198,7 +231,8 @@ describe('MultiSig Wallet', () => { const result = await multiSigWallet.submitTransaction( mainToken.address, EMPTY_BYTES, - encoded_transfer_function, + encoded_transfer_function, + 0, {"from": accounts[0]} ); txIndex4 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 386ad32..5141248 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -151,8 +151,11 @@ describe('Proposal flow', () => { },{ type: 'bytes', name: '_data' + },{ + type: 'uint256', + name: '_expireTimestamp' }] - }, [FTHMToken.address, EMPTY_BYTES, encoded_transfer_function]); + }, [FTHMToken.address, EMPTY_BYTES, encoded_transfer_function, 0]); description_hash = web3.utils.keccak256(PROPOSAL_DESCRIPTION); description_hash_2 = web3.utils.keccak256(PROPOSAL_DESCRIPTION_2); @@ -183,7 +186,8 @@ describe('Proposal flow', () => { const result = await multiSigWallet.submitTransaction( FTHMToken.address, EMPTY_BYTES, - _encodeTransferFunction(_account), + _encodeTransferFunction(_account), + 0, {"from": accounts[0]} ); let txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -351,7 +355,8 @@ describe('Proposal flow', () => { const result = await multiSigWallet.submitTransaction( mainTokenGovernor.address, EMPTY_BYTES, - encodedConfirmation1, + encodedConfirmation1, + 0, {"from": accounts[0]} ); txIndex1 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -407,7 +412,8 @@ describe('Proposal flow', () => { const result = await multiSigWallet.submitTransaction( FTHMToken.address, EMPTY_BYTES, - _encodeTransferFunction(_account), + _encodeTransferFunction(_account), + 0, {"from": accounts[0]} ); txIndex4 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -542,7 +548,8 @@ describe('Proposal flow', () => { const result = await multiSigWallet.submitTransaction( mainTokenGovernor.address, EMPTY_BYTES, - encodedConfirmation1, + encodedConfirmation1, + 0, {"from": accounts[0]} ); txIndex2 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; diff --git a/scripts/tests/dao/governance/token-creation-though-gov.test.js b/scripts/tests/dao/governance/token-creation-though-gov.test.js index 559b201..85f21f7 100644 --- a/scripts/tests/dao/governance/token-creation-though-gov.test.js +++ b/scripts/tests/dao/governance/token-creation-though-gov.test.js @@ -152,7 +152,8 @@ describe('Token Creation Through Governance', () => { const result = await multiSigWallet.submitTransaction( FTHMToken.address, EMPTY_BYTES, - _encodeTransferFunction(_account), + _encodeTransferFunction(_account), + 0, {"from": accounts[0]} ); txIndex4 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -319,7 +320,8 @@ describe('Token Creation Through Governance', () => { const result = await multiSigWallet.submitTransaction( mainTokenGovernor.address, EMPTY_BYTES, - encodedConfirmation1, + encodedConfirmation1, + 0, {"from": accounts[0]} ); txIndex1 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index 53455cd..2af2c22 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -297,7 +297,8 @@ describe("Staking Test", () => { const result = await multiSigWallet.submitTransaction( FTHMToken.address, EMPTY_BYTES, - _encodeTransferFunction(_account, _value), + _encodeTransferFunction(_account, _value), + 0, {"from": accounts[0]} ); txIndex4 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -326,7 +327,8 @@ describe("Staking Test", () => { const result = await multiSigWallet.submitTransaction( vaultService.address, EMPTY_BYTES, - _encodeAddSupportedTokenFunction(_token), + _encodeAddSupportedTokenFunction(_token), + 0, {"from": accounts[0]} ); const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -552,12 +554,23 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + 20); const totalAmountOfStakedToken = await stakingService.totalAmountOfStakedToken() const totalAmountOfStreamShares = await stakingService.totalStreamShares() - + const MAIN_STREAM_ID = 0 + assert.equal(totalAmountOfStakedToken.toString(),"0") assert.equal(totalAmountOfStreamShares.toString(),"0") console.log("----- After all the locks are completely unlocked ------") console.log("totalAmountOfStakedToken: ", totalAmountOfStakedToken.toString()); console.log("totalAmountOfStreamShares: ", totalAmountOfStreamShares.toString()); + + + await stakingService.withdrawAllStreams({from: staker_1}); + await stakingService.withdrawAllStreams({from: staker_2}); + await stakingService.withdrawAllStreams({from: staker_3}); + await stakingService.withdrawAllStreams({from: staker_4}); + + const totalAmountOfStreamTotalUserPendings = await stakingService.streamTotalUserPendings(MAIN_STREAM_ID) + assert.equal(totalAmountOfStreamTotalUserPendings.toString(),"0") + console.log("totalAmountOfStreamPending: ", totalAmountOfStreamTotalUserPendings.toString()); }); }); @@ -608,7 +621,8 @@ describe("Staking Test", () => { _scheduleTimes, _scheduleRewards, _tau - ), + ), + 0, {"from": accounts[0]} ); const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -634,7 +648,7 @@ describe("Staking Test", () => { it("Should Create a Stream", async() => { // Once createStream is called, the proposal will become live once start time is reached const RewardProposalAmountForAStream = web3.utils.toWei('800', 'ether'); - await streamReward1.approve(stakingService.address, RewardProposalAmountForAStream, {from:stream_rewarder_1}) + await streamReward1.approve(vaultService.address, RewardProposalAmountForAStream, {from:stream_rewarder_1}) await stakingService.createStream(1,RewardProposalAmountForAStream, {from: stream_rewarder_1}); await blockchain.mineBlock(await _getTimeStamp() + 20); }) @@ -676,7 +690,8 @@ describe("Staking Test", () => { _scheduleTimes, _scheduleRewards, _tau - ), + ), + 0, {"from": accounts[0]} ); const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -701,7 +716,7 @@ describe("Staking Test", () => { it("Should Create a Stream - 2", async() => { const RewardProposalAmountForAStream = web3.utils.toWei('1000', 'ether'); - await streamReward2.approve(stakingService.address, RewardProposalAmountForAStream, {from:stream_rewarder_2}) + await streamReward2.approve(vaultService.address, RewardProposalAmountForAStream, {from:stream_rewarder_2}) await stakingService.createStream(2,RewardProposalAmountForAStream, {from: stream_rewarder_2}); }) @@ -1039,10 +1054,13 @@ describe("Staking Test", () => { assert.equal(totalAmountOfStreamShares.toString(),"0") }) + + it('Should have balances of unlocked FTHM with rewards after all unlocks', async() => { - await stakingService.withdrawStream(0, {from: staker_2}) - await stakingService.withdrawStream(0, {from: staker_3}) - await stakingService.withdrawStream(0, {from: staker_4}) + const MAIN_STREAM_ID = 0; + await stakingService.withdrawAllStreams({from: staker_2}) + await stakingService.withdrawAllStreams({from: staker_3}) + await stakingService.withdrawAllStreams({from: staker_4}) let staker_2Balance = await FTHMToken.balanceOf(staker_2); let staker_3Balance = await FTHMToken.balanceOf(staker_3); let staker_4Balance = await FTHMToken.balanceOf(staker_4); @@ -1058,6 +1076,19 @@ describe("Staking Test", () => { const toBeReleasedInFirstYearRewards = 10000; expect(totalRewardsDistributed).to.be.above(toBeReleasedInFirstYearRewards); console.log("total rewards released in FTHM Token - after 370 + ~20 days - early unstake penalty", totalRewardsDistributed) + + }) + + it('Should have zero stream pending', async() => { + const MAIN_STREAM_ID = 0; + const FIRST_STREAM_ID = 1 + const SECOND_STREAM_ID = 2 + const totalAmountOfMAINStreamTotalUserPendings = await stakingService.streamTotalUserPendings(MAIN_STREAM_ID) + const totalAmountOfFIRSTStreamTotalUserPendings = await stakingService.streamTotalUserPendings(FIRST_STREAM_ID) + const totalAmountOfSECONDStreamTotalUserPendings = await stakingService.streamTotalUserPendings(SECOND_STREAM_ID) + assert.equal(totalAmountOfMAINStreamTotalUserPendings.toString(),"0") + assert.equal(totalAmountOfFIRSTStreamTotalUserPendings.toString(),"0") + assert.equal(totalAmountOfSECONDStreamTotalUserPendings.toString(),"0") }) // The following tests are just to check individual test cases @@ -1127,7 +1158,9 @@ describe("Staking Test", () => { EMPTY_BYTES, _encodeWithdrawPenaltyFunction( _penaltyReceiver - ), {"from": accounts[0]} + ), + 0, + {"from": accounts[0]} ) const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -1161,7 +1194,9 @@ describe("Staking Test", () => { EMPTY_BYTES, _encodeAdminPause( _flag - ), {"from": accounts[0]} + ), + 0, + {"from": accounts[0]} ) const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -1193,7 +1228,9 @@ describe("Staking Test", () => { EMPTY_BYTES, _encodeAdminPause( _flag - ), {"from": accounts[0]} + ), + 0, + {"from": accounts[0]} ) const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; @@ -1218,22 +1255,11 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + 100); }) - it('Should not be initalizable twice', async() => { + it('Should not be initalizable twice - Vault', async() => { const errorMessage = "Vault: Already Initialized"; await shouldRevert( - vaultService.initVault([FTHMToken.address], {gas: 8000000}), - errTypes.revert, - errorMessage - ); - - }) - - it('Should not be initalizable twice vault init owner', async() => { - - const errorMessage = "Initializable: contract is already initialized"; - await shouldRevert( - vaultService.initAdminAndOperator(multiSigWallet.address,stakingService.address, {gas: 8000000}), + vaultService.initVault(multiSigWallet.address,[FTHMToken.address], {gas: 8000000}), errTypes.revert, errorMessage ); From 8f78f27908f304411135d32a10412731c66eff5b Mon Sep 17 00:00:00 2001 From: ssubik Date: Tue, 27 Dec 2022 15:42:30 +0545 Subject: [PATCH 12/77] fixing govn criticals --- audit-report/Fathom_DAO.md | 6 ++--- contracts/dao/governance/Governor.sol | 2 +- .../dao/governance/MainTokenGovernor.sol | 9 ++++++++ .../extensions/GovernorTimelockControl.sol | 8 ++++--- .../GovernorVotesQuorumFraction.sol | 2 +- .../dao/governance/interfaces/IGovernor.sol | 6 +++++ .../dao/staking/packages/StakingHandler.sol | 23 ++++++++++++++++--- 7 files changed, 45 insertions(+), 11 deletions(-) diff --git a/audit-report/Fathom_DAO.md b/audit-report/Fathom_DAO.md index b780340..46082f0 100644 --- a/audit-report/Fathom_DAO.md +++ b/audit-report/Fathom_DAO.md @@ -133,7 +133,7 @@ In the function [`removeOwner`](https://github.com/Into-the-Fathom/fathom-dao-sm ##### Recommendation We recommend adding signature revocation mechanisms for signatures of the removed owners to the function `removeOwner`. -#### [NEW] There is no function that implements the `_cancel` proposal in `MainTokenGovernor`[NOTDONE, understand more] +#### [NEW] There is no function that implements the `_cancel` proposal in `MainTokenGovernor`[DONE] ##### Description The contract [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) lacks a function that would implement the internal function [`_cancel`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L91), that allows you to cancel the execution of `proposal` with `TimelockController`. This can make it impossible to cancel the execution of a potentially dangerous call. ##### Recommendation @@ -242,7 +242,7 @@ This creates a risk that if `MINTER_ROLE` is compromised by an attacker, the adm We recommend adding separate functions to grant and revoke the `MINTER_ROLE`, which will also add and remove addresses from the `isWhitelisted` list. -#### [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[NOTDONE] +#### [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[ASK MAX about targets] ##### Description In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. ##### Recommendation @@ -281,7 +281,7 @@ In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-c ##### Recommendation We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) extension from the OpenZepplin library and replace the `transfer` and `transferFrom` calls with `safeTransfer` and `safeTransferFrom`. -#### [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`{DONE} +#### [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`{NOTDONE} ##### Description In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 3dc486c..270fe56 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -28,7 +28,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); - //AuditFix There is no validation for `maxTargets` when executing in `Governor` - ASK THIS, to make it constant or as argument + //AuditFix There is no validation for `maxTargets` when executing in `Governor` - ASK THIS, to make it modifiable uint256 public constant MAX_TARGETS = uint256(10); string private _name; uint256[] private proposalIds; diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index 22979a0..ffefff3 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -42,6 +42,15 @@ contract MainTokenGovernor is return super.propose(targets, values, calldatas, description); } + function cancelProposal( + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + bytes32 descriptionHash + ) public onlyMultiSig override returns (uint256) { + return _cancel(targets, values, calldatas, descriptionHash); + } + function proposalThreshold() public view override(Governor, GovernorSettings) returns (uint256) { return super.proposalThreshold(); } diff --git a/contracts/dao/governance/extensions/GovernorTimelockControl.sol b/contracts/dao/governance/extensions/GovernorTimelockControl.sol index 528d285..096a09b 100644 --- a/contracts/dao/governance/extensions/GovernorTimelockControl.sol +++ b/contracts/dao/governance/extensions/GovernorTimelockControl.sol @@ -11,7 +11,7 @@ import "../TimelockController.sol"; abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { TimelockController private _timelock; mapping(uint256 => bytes32) private _timelockIds; - + mapping(uint256 => bool) private isProposalExecuted; event TimelockChange(address oldTimelock, address newTimelock); constructor(TimelockController timelockAddress) { @@ -49,7 +49,7 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { function state(uint256 proposalId) public view virtual override(IGovernor, Governor) returns (ProposalState) { ProposalState status = super.state(proposalId); - + if (status != ProposalState.Succeeded) { return status; } @@ -76,13 +76,15 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { } function _execute( - uint256 /* proposalId */, + uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal virtual override { + require(!isProposalExecuted[proposalId],"_execute: proposal already executed"); _timelock.executeBatch{ value: msg.value }(targets, values, calldatas, 0, descriptionHash); + isProposalExecuted[proposalId] = true; } // This function can reenter through the external call to the timelock, but we assume the timelock is trusted and diff --git a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol b/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol index 6de97fe..0573b68 100644 --- a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol +++ b/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol @@ -9,7 +9,7 @@ import "./GovernorVotes.sol"; abstract contract GovernorVotesQuorumFraction is GovernorVotes { uint256 private _quorumNumerator; - uint256 public constant MINIMUM_QUORUM_NUMERATOR = uint256(4); + uint256 public constant MINIMUM_QUORUM_NUMERATOR = uint256(2); event QuorumNumeratorUpdated(uint256 oldQuorumNumerator, uint256 newQuorumNumerator); /** diff --git a/contracts/dao/governance/interfaces/IGovernor.sol b/contracts/dao/governance/interfaces/IGovernor.sol index db6b42f..00c323e 100644 --- a/contracts/dao/governance/interfaces/IGovernor.sol +++ b/contracts/dao/governance/interfaces/IGovernor.sol @@ -45,6 +45,12 @@ abstract contract IGovernor is IERC165 { string memory description ) public virtual returns (uint256 proposalId); + function cancelProposal( + address[] memory targets, + uint256[] memory values, + bytes[] memory calldatas, + bytes32 descriptionHash + ) public virtual returns (uint256); function execute( address[] memory targets, uint256[] memory values, diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index c7198eb..14f3f74 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -10,10 +10,8 @@ import "../interfaces/IStakingHandler.sol"; import "../vault/interfaces/IVault.sol"; import "../../../common/security/ReentrancyGuard.sol"; import "../../../common/security/AdminPausable.sol"; -import "../../../common/SafeERC20.sol"; // solhint-disable not-rely-on-time contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, ReentrancyGuard, AdminPausable { - using SafeERC20 for IERC20; bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); /** @@ -256,6 +254,24 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R } } + function updateConfig( + Weight memory _weight, + address _voteToken, + address _rewardsCalculator, + VoteCoefficient memory _voteCoef, + uint256 _maxLockPeriod, + uint256 _maxLockPositions + ) public onlyRole(DEFAULT_ADMIN_ROLE) { + weight = _weight; + voteToken = _voteToken; + rewardsCalculator = _rewardsCalculator; + voteShareCoef = _voteCoef.voteShareCoef; + voteLockCoef = _voteCoef.voteLockCoef; + maxLockPeriod = _maxLockPeriod; + maxLockPositions = _maxLockPositions; + } + + function updateVault(address _vault) public override onlyRole(DEFAULT_ADMIN_ROLE) { // enforce pausing this contract before updating the address. // This mitigates the risk of future invalid reward claims @@ -276,7 +292,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R require(lockPeriod <= maxLockPeriod, "max lock period"); _updateStreamRPS(); _lock(account, amount, lockPeriod); - IERC20(mainToken).safeTransferFrom(msg.sender, address(vault), amount); + IERC20(mainToken).transferFrom(msg.sender, address(vault), amount); } function _verifyUnlock(uint256 lockId) internal view { @@ -286,4 +302,5 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R require(lock.amountOfToken > 0, "no lock amount"); require(lock.owner == msg.sender, "bad owner"); } + } From d5b1151fc90571e11b027fedcec84f71165eab78 Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 28 Dec 2022 18:41:03 +0545 Subject: [PATCH 13/77] audit fixes both warnings and majors on work --- audit-report/Fathom_DAO.md | 64 ++++++------- contracts/common/security/AdminPausable.sol | 4 + contracts/dao/governance/Governor.sol | 22 ++++- .../dao/governance/MainTokenGovernor.sol | 27 +++++- .../extensions/GovernorTimelockControl.sol | 1 + .../governance/extensions/GovernorVotes.sol | 1 + .../staking/interfaces/IStakingHandler.sol | 11 ++- .../dao/staking/packages/StakingHandler.sol | 51 +++++----- .../dao/staking/vault/interfaces/IVault.sol | 9 +- .../staking/vault/packages/VaultPackage.sol | 31 +++++- contracts/dao/treasury/MultiSigWallet.sol | 3 +- .../test/2_deploy_init_staking_proxy.js | 17 +--- .../migrations/test/3_add_vault_operator.js | 4 - .../migrations/test/6_setup_vault_tokens.js | 94 +++++++++++++++---- 14 files changed, 231 insertions(+), 108 deletions(-) diff --git a/audit-report/Fathom_DAO.md b/audit-report/Fathom_DAO.md index 46082f0..806c75d 100644 --- a/audit-report/Fathom_DAO.md +++ b/audit-report/Fathom_DAO.md @@ -140,7 +140,7 @@ The contract [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao We recommend adding logic that would allow you to cancel the execution of `proposal` and call the internal function `_cancel`. -#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[NOTDONE,Is this true Max Ji. Feels not] +#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE,Is this true Max Ji. Feels not] ##### Description A change of the `timelock` parameter in the [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L22) contract can lead to already executed `proposals` being able to be executed again. This is connected to the fact that the execution status of the transaction is saved only in the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, and the `GovernorTimelockControl` contract makes calls to the `TimelockController` functions to get the `proposals` status in the [`state`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L50) function. ##### Recommendation @@ -176,7 +176,7 @@ We recommend discarding the `updateConfig` function and consider mechanisms for ### MAJOR -#### [NEW] In `MultiSigWallet` there's no parameter defining minimum amount of signatures[NOTDONE but would have bad impact on test] +#### [NEW] In `MultiSigWallet` there's no parameter defining minimum amount of signatures[NOTDONE but would have bad impact on test, MAX] ##### Description The parameter [`_numConfirmationsRequired`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L77) is checked in the constructor and in the function [`changeRequirement`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L116), that is not equal to `0`, however, when multi-signature is set, it allows the value `1`, and the contract may be used by one of the `owners`. @@ -197,7 +197,7 @@ We recommend to consider a permissions policy or add the `DEFAULT_ADMIN_ROLE` fo #### [NEW] There is no validation for `maxTargets` when executing in `Governor` -##### Description[ASK THIS, easier] +##### Description[DONE] In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L142) function there is no validation of the maximum number of `targets`. This can cause `proposal` to have so many calls to external contracts that the execution transaction will face a "gas bomb" effect. This means a large amount of gas consumption or restricted gas limit block. ##### Recommendation We recommend including the `maxTargets` parameter for `_targets`, the maximum number of `_targets` in the `proposal`. @@ -210,11 +210,11 @@ In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contract We recommend adding the `updateMultisig` function, but so that only the old `multisig` could call it. -#### [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE, how to do? ask more feedback] +#### [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE, how to do? ask more feedback, MAX] ##### Description There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. ##### Recommendation -We recommend adding the `emergencyExit` function to the contract, which can be called by Governance by majority vote without confirmation with `multisig`. The function can be called once, its call stops the work of the contract. After calling this function, recovery is only possible by migrating to a new contract. +We recommend adding the `emergencyExit` function to the contract, which can be called by Governance by majorit fy vote without confirmation with `multisig`. The function can be called once, its call stops the work of the contract. After calling this function, recovery is only possible by migrating to a new contract. #### [NEW] It is possible to set a null address in `GovernorTimelockControl` when updating `timelock`.[DONE] @@ -224,7 +224,7 @@ In the `GovernorTimelockControl` contract it is possible to set a null address w We recommend adding a check that the address `newTimelock != address(0)` -#### [NEW] There is no validation for null values for `newQuorumNumerator` in `GovernorVotesQuorumFraction`[NOTDONE,Ask Max] +#### [NEW] There is no validation for null values for `newQuorumNumerator` in `GovernorVotesQuorumFraction`[DONE,Ask Max] ##### Description In the `GovernorVotesQuorumFraction` contract in the [`_updateQuorumNumerator`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol#L55) function it is possible to set `_quorumNumerator` to `0` value, which would lead to a complete voting stop. ##### Recommendation @@ -251,14 +251,14 @@ We recommend fixing the possibility of withdrawal of tokens of the `ERC20` stand - It is a must to implement the `addSupportingTokens` function due to the fact that various tokens of the `ERC20` standard can be transferred to the Governance balance. Governance must work only with trusted tokens like USDT, USDC, etc. This function will make it possible to create a list of trusted tokens. Adding a token should only be done through Governance. - Add a check to the `execute` function to confirm that `_target` is the contract address from the trusted tokens. And only in this case pass it to the `TimelockController` address. -#### [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[NOTDONE, ask anton] +#### [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE but, ask anton] ##### Description The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol) contract lacks the ability to suspend a contract in an emergency and migrate assets to a new compatible `VaultPackage` contract. ##### Recommendation We recommend adding the `emergencyExit` function in the contract which permanently blocks contract function calls for `REWARD_OPERATOR_ROLE`, and adding the `migrate` function, which allows to move tokens and token balances to a new version of `VaultPackage`. -#### [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE, please explain more] +#### [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[DONE, please explain more] ##### Description In the `StakingHandlers` contract, calling the function [`updateVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L269) can cause all contract functions that work with balances and `VaultPackage` functions to be blocked. ##### Recommendation @@ -281,7 +281,7 @@ In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-c ##### Recommendation We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) extension from the OpenZepplin library and replace the `transfer` and `transferFrom` calls with `safeTransfer` and `safeTransferFrom`. -#### [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`{NOTDONE} +#### [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`{NOTDONE, Ask Anton} ##### Description In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. @@ -292,7 +292,7 @@ We recommend: - adding a separate `withdraw` function that would allow the `DEFAULT_ADMIN_ROLE` address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). - replacing [token transfers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) to `VaultPackage` in the `StakingHandlers` contract with calling the `deposit` function of the `VaultPackage` contract. It should have a prior `safeApprove` call to token in the `VaultPackage` contract. -#### [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[NOTDONE] +#### [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE] ##### Description In the `StakingHandlers` contract the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function does not allocate tokens for rewards `MAIN_STREAM`, as it happens when [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) is called. This may result in the block of the `withdrawStream` function call from the `MAIN_STREAM` of tokens and rewards for some users, if the amount in `VaultPackage` is less than the amount stated in `scheduleRewards`. ##### Recommendation @@ -440,7 +440,7 @@ return ``` -#### [NEW] Penalty can be bigger than stake in the `StakingInternals`[DONE, but readability part NOTDONE] +#### [NEW] Penalty can be bigger than stake in the `StakingInternals`[DONE] ##### Description @@ -464,7 +464,7 @@ It is also worth moving the value of `100000` into a separate constant variable ### WARNING -#### [NEW] Modifier `onlyOwnerOrGov` creates a complex confirmation structure in case of `Governance` calls in the `MultiSigWallet.sol` +#### [NEW] Modifier `onlyOwnerOrGov` creates a complex confirmation structure in case of `Governance` calls in the `MultiSigWallet.sol`[Ask Max] ##### Description The modifier [`onlyOwnerOrGov`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L29) uses the following construction: ```solidity @@ -501,7 +501,7 @@ And so each function in the sequence: ##### Recommendation We recommend removing `Governance` from this modifier and give the permission to `MultiSigWallet` administration to authorized representatives only, or review the logic of `Governance` and approving of `proposals` from `MultiSigWallet`. -#### [NEW] No parameter check when adding transaction in `MultiSigWallet` +#### [NEW] No parameter check when adding transaction in `MultiSigWallet`[Ask Max] ##### Description In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. Based on the logic of the contract, there may be the following cases: @@ -512,7 +512,7 @@ Based on the logic of the contract, there may be the following cases: ##### Recommendation We recommend adding parameter checking when adding a transaction according to possible cases of using `MultiSigWallet`. -#### [NEW] Missing validation, that the bytecode of address `_to` did not change while running a transaction in `MultiSigWallet` +#### [NEW] Missing validation, that the bytecode of address `_to` did not change while running a transaction in `MultiSigWallet`[DONE] ##### Description In the functions [`confirmTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L129) and [`executeTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L137) there's no validation that the bytecode of address `_to` did not change as an EOA or smart contract. In this case, the following situations are possible: @@ -540,21 +540,21 @@ assembly { codeHash := extcodehash(account) } return (codeHash != isWhitelistedBytesCode[_to]); ``` -#### [NEW] There's no ETH balance validation when adding a non-zero transaction `_value` in `MultiSigWallet` +#### [NEW] There's no ETH balance validation when adding a non-zero transaction `_value` in `MultiSigWallet`[DONE] ##### Description In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no verifying that `MultiSigWallet` account has the necessary amount on the balance for the transaction. In case of approval by `owners` , the transaction will be approved but not executed. ##### Recommendation We recommend adding balance check while adding a transaction with a non-zero value `_value`. -#### [NEW] There is no time limit for executing proposal in `Governor.sol` +#### [NEW] There is no time limit for executing proposal in `Governor.sol`[DONE] ##### Description The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract has no parameters for the time limit on `proposal` execution. This can result in no longer relevant proposal being executed after a period of time. ##### Recommendation We recommend adding the `lifetime` parameter, the runtime of `proposal`, and check it during the execution. -#### [NEW] There is no check for gas consumption in `Governor` +#### [NEW] There is no check for gas consumption in `Governor`[ASK ANTON FOR MAX GAS LIMIT] ##### Description In the [Governor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L142) contract, the `propose` function lacks a parameter and a check for gas limit for calls to `targets`. This could make it possible for a call to a vulnerable external contract to be able to loop the call and perform a DDoS attack with high gas consumption. @@ -562,7 +562,7 @@ In the [Governor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/ Consider implementing the `gasLimit` parameter - the maximum gas amount for a call, for each of the `targets`. -#### [NEW] `confirmProposal` is possible for both active and inactive proposals in `Governor` +#### [NEW] `confirmProposal` is possible for both active and inactive proposals in `Governor`[DONE] ##### Description In the `Governor` contract the function [`confirmProposal`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L173) can be called for both active and inactive proposals. ##### Recommendation @@ -572,7 +572,7 @@ ProposalState status = state(proposalId); require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); ``` -#### [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController` +#### [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[NOTDONE] ##### Description In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) contracts the `execute` functions do not check the `msg.value` balance value needed to execute `_targets`, which would result in gas consumption even if the amount of `ETH` is not enough. ##### Recommendation @@ -581,7 +581,7 @@ We recommend adding: - a check that the `msg.value` passed to the `execute` function is greater than the total value needed for the execution of the `targets` calls in the proposal. - a return of the remaining `ETH` balance to the sender of the transaction after the execution of `proposal`. -#### [NEW] There is no check for zero value for `_token`, `_multiSig` and `_timelock` in `Governor`, `GovernorTimelockControl`, `MainTokenGovernor` +#### [NEW] There is no check for zero value for `_token`, `_multiSig` and `_timelock` in `Governor`, `GovernorTimelockControl`, `MainTokenGovernor`[DONE] ##### Description In the constructors of [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L67), [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L17) and [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L21) contracts it is possible to set zero values for `tokenAddress`, `_multiSig`, `timelock` contracts. @@ -596,13 +596,13 @@ In the [`_setProposalThreshold`](https://github.com/Into-the-Fathom/fathom-dao-s ##### Recommendation We recommend adding a check that `newProposalThreshold` is not zero. -#### [NEW] There is no limit on the number of proposals for one proposer in `Governor`[] +#### [NEW] There is no limit on the number of proposals for one proposer in `Governor`[Ask MAX] ##### Description In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. ##### Recommendation We recommend adding a limit to the number of proposals with `active` and `pending` status. -#### [NEW] A missing check that tokens are on the balance when calling the `payRewards` function in the `VaultPackage` contract +#### [NEW] A missing check that tokens are on the balance when calling the `payRewards` function in the `VaultPackage` contract[NOTDONE] ##### Description In the `VaultPackage` contract when calling the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31) there is no processing of errors such as: @@ -613,31 +613,31 @@ In the `VaultPackage` contract when calling the function [`payRewards`](https:// We recommend adding a check that tokens are on the balance and that `amount != 0`, and return error using `custom errors` (`revert CustomError`) or with `require`. -#### [NEW] There is no limit on the maximum number of active `streams` in the `StakingHandlers` contract +#### [NEW] There is no limit on the maximum number of active `streams` in the `StakingHandlers` contract[NOTDONE] ##### Description In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) contract there is no limit on the maximum number of active `streams`. This creates a situation of an uncontrolled gas consumption when dealing with contract functions and can lead to DoS. ##### Recommendation We recommend adding a parameter that would allow to limit the maximum number of active `streams`. -#### [NEW] Incorrect processing of contract modifiers `Initializable` in the `StakingHanders` contract +#### [NEW] Incorrect processing of contract modifiers `Initializable` in the `StakingHanders` contract[DONE] ##### Description The contract [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) uses the `upgradeable proxy` template, at the same time the work with the modifiers of the `Initializable` contract, which is inherited from the `AdminPausable`, is not performed correctly. ##### Recommendation We recommend adjusting the contract according to [OpenZeppelin's recommendations](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/Initializable.sol): -- The contract constructor must contain a call to the `_disableInitializers` function to disable contract initialization at the implementation level and prevent an attacker from using the contract's implementation -- The initializer (in the case of the `StakingHandlers` contract it is `initializeStaking`) must contain the `initializer` modifier +- The contract constructor must contain a call to the `_disableInitializers` function to disable contract initialization at the implementation level and prevent an attacker from using the contract's implementation[DONE] +- The initializer (in the case of the `StakingHandlers` contract it is `initializeStaking`) must contain the `initializer` modifier[DONE] - The initialiser of the parent contract must be with the `onlyInitializing` modifier (in the case of the `StakingHandlers` contract, it is a call to the `pausableInit` of the [`AdminPausable`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/security/AdminPausable.sol#L28) contract) -#### [NEW] It is possible for any user to call `createStream` in the `StakingHandlers` contract +#### [NEW] It is possible for any user to call `createStream` in the `StakingHandlers` contract[DONE] ##### Description In the `StakingHandlers` contract any user can call the function [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L134) and run `stream`. This bears a risk that attackers could mislead a potential user into giving `approve` to the `StakingHandlers` contract and force them to call `createStream`. `createStream` will charge the user the necessary amount of money for the rewards. ##### Recommendation We recommend adding a condition that `createStream` can only be called from the `streamOwner` address. #### [NEW] Possible overflow with calculations -##### Description +##### Description[NOTDONE] In the next lines there is a possible overflow: - [`RewardsLibrary.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L70) @@ -658,7 +658,7 @@ We recommend to use [`muldiv`](https://xn--2-umb.com/21/muldiv/index.html) to mu We also recommend to update `voteLockCoef` [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L42) and add checks that it is not zero (to prevent division by zero) and that it is not too big in order to avoid overflow in `BoringMath`. -#### [NEW] Multiple `streams` can be active at the same time with the same parameters in `StakingHandler.sol ` +#### [NEW] Multiple `streams` can be active at the same time with the same parameters in `StakingHandler.sol `[] ##### Description In the contract [StakingHandler]( @@ -670,7 +670,7 @@ https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6 We recommend adding checks that `stream` is added before submitting a new one. -#### [NEW] There is no limit for the amount of schedules on streams in `StakingHandlers` +#### [NEW] There is no limit for the amount of schedules on streams in `StakingHandlers`[NOTDONE] ##### Description @@ -678,10 +678,10 @@ There is no limit for the amount of schedules on streams in the contract [`Staki https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L103-L111). This can cause the block gas limit to be exceeded. ##### Recommendation -We recommend limiting values of `scheduleTimes` or `scheduleRewards`. +We recommend limiting values of `scheduleTimes` or `scheduleRewards`.[NOTDONE] -#### [NEW] It is possible to remove tokens that are used by another contract in `VaultPackage` +#### [NEW] It is possible to remove tokens that are used by another contract in `VaultPackage`[NOTDONE] ##### Description Calling the [`removeSupportedToken`]( diff --git a/contracts/common/security/AdminPausable.sol b/contracts/common/security/AdminPausable.sol index b7ea4ce..c5e4831 100644 --- a/contracts/common/security/AdminPausable.sol +++ b/contracts/common/security/AdminPausable.sol @@ -21,6 +21,10 @@ contract AdminPausable is IAdminPausable, AccessControlUpgradeable { /// @param flags flags variable is used for pausing this contract. function adminPause(uint256 flags) external override onlyRole(PAUSE_ROLE) { // pause role can pause the contract, however only default admin role can unpause + _adminPause(flags); + } + + function _adminPause(uint256 flags) internal { require((paused & flags) == paused || hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "only admin can unpause"); paused = flags; } diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 270fe56..c9b343f 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -24,12 +24,13 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { event ConfirmProposal(address indexed signer, uint indexed proposalId); event RevokeConfirmation(address indexed signer, uint indexed proposalId); event ExecuteProposal(address indexed signer, uint indexed proposalId); - event MultiSigUpdated(address indexed newMultiSig, address oldMultiSig); + event MultiSigUpdated(address newMultiSig, address oldMultiSig); + event MaxTargetUpdated(uint256 newMaxTargets, uint256 oldMaxTargets); bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); //AuditFix There is no validation for `maxTargets` when executing in `Governor` - ASK THIS, to make it modifiable - uint256 public constant MAX_TARGETS = uint256(10); + uint256 public maxTargets; string private _name; uint256[] private proposalIds; @@ -66,9 +67,12 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { _; } - constructor(string memory name_, address _multiSig) EIP712(name_, version()) { + constructor(string memory name_, address _multiSig, uint256 _maxTargets) EIP712(name_, version()) { + require(_multiSig != address(0),"multiSig address cant be zero address"); + require(_maxTargets != 0,"maxTarget cant be zero"); _name = name_; multiSig = _multiSig; + maxTargets = _maxTargets; } receive() external payable virtual { @@ -155,7 +159,8 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { require(targets.length == values.length, "Governor: invalid proposal length"); require(targets.length == calldatas.length, "Governor: invalid proposal length"); require(targets.length > 0, "Governor: empty proposal"); - require(targets.length <= MAX_TARGETS,"Governor: invalid proposal length"); + require(targets.length <= maxTargets,"Governor: invalid proposal length"); + ProposalCore storage proposal = _proposals[proposalId]; require(proposal.voteStart.isUnset(), "Governor: proposal already exists"); @@ -175,7 +180,8 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { function confirmProposal(uint _proposalId) public onlyMultiSig notExecuted(_proposalId) notConfirmed(_proposalId) { isConfirmed[_proposalId] = true; - + ProposalState status = state(_proposalId); + require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); emit ConfirmProposal(msg.sender, _proposalId); } @@ -193,6 +199,12 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { emit MultiSigUpdated(newMultiSig, multiSig); multiSig = newMultiSig; } + + function updateMaxTargets(uint256 newMaxTargets) public onlyMultiSig{ + require(newMaxTargets != 0,"updateMaxTargets: newMaxTargets cant be zero"); + emit MaxTargetUpdated(newMaxTargets, maxTargets); + maxTargets = newMaxTargets; + } function getProposals(uint _numIndexes) public view override returns (string[] memory, string[] memory, string[] memory) { uint len = proposalIds.length; diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index ffefff3..262a886 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -9,6 +9,8 @@ import "./extensions/GovernorCountingSimple.sol"; import "./extensions/GovernorVotes.sol"; import "./extensions/GovernorVotesQuorumFraction.sol"; import "./extensions/GovernorTimelockControl.sol"; +import "../tokens/ERC20/IERC20.sol"; +import "../../common/SafeERC20.sol"; contract MainTokenGovernor is Governor, @@ -17,7 +19,10 @@ contract MainTokenGovernor is GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl -{ +{ + using SafeERC20 for IERC20; + mapping(address => bool) public isSupportedToken; + constructor( IVotes _token, TimelockController _timelock, @@ -26,7 +31,7 @@ contract MainTokenGovernor is uint256 _votingPeriod, uint256 _initialProposalThreshold ) - Governor("MainTokenGovernor", _multiSig) + Governor("MainTokenGovernor", _multiSig,20) GovernorSettings(_initialVotingDelay, _votingPeriod, _initialProposalThreshold) GovernorVotes(_token) GovernorVotesQuorumFraction(4) @@ -75,6 +80,22 @@ contract MainTokenGovernor is return super.state(proposalId); } + function addSupportingToken(address _token) public onlyGovernance { + require(!isSupportedToken[_token], "Token already exists"); + isSupportedToken[_token] = true; + } + + function removeSupportingToken(address _token) public onlyGovernance { + require(isSupportedToken[_token], "Token does not exist"); + isSupportedToken[_token] = false; + } + + function withdrawToken(address _token, address _withdrawTo) public onlyMultiSig { + require(isSupportedToken[_token],"Token does not exist"); + uint256 balance = IERC20(_token).balanceOf(address(this)); + IERC20(_token).safeTransfer(_withdrawTo, balance); + } + function _execute( uint256 proposalId, address[] memory targets, @@ -98,4 +119,6 @@ contract MainTokenGovernor is function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) { return super._executor(); } + + } diff --git a/contracts/dao/governance/extensions/GovernorTimelockControl.sol b/contracts/dao/governance/extensions/GovernorTimelockControl.sol index 096a09b..be3a231 100644 --- a/contracts/dao/governance/extensions/GovernorTimelockControl.sol +++ b/contracts/dao/governance/extensions/GovernorTimelockControl.sol @@ -15,6 +15,7 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { event TimelockChange(address oldTimelock, address newTimelock); constructor(TimelockController timelockAddress) { + require(address(timelockAddress) != address(0),"timelockAddress cant be zero address"); _updateTimelock(timelockAddress); } diff --git a/contracts/dao/governance/extensions/GovernorVotes.sol b/contracts/dao/governance/extensions/GovernorVotes.sol index 780a389..94bd019 100644 --- a/contracts/dao/governance/extensions/GovernorVotes.sol +++ b/contracts/dao/governance/extensions/GovernorVotes.sol @@ -11,6 +11,7 @@ abstract contract GovernorVotes is Governor { IVotes public immutable token; constructor(IVotes tokenAddress) { + require(address(tokenAddress) != address(0),"tokenAddress cant be zero address"); token = tokenAddress; } diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index 934323a..9878392 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -13,14 +13,17 @@ interface IStakingHandler { address _mainToken, address _voteToken, Weight calldata _weight, - uint256[] memory scheduleTimes, - uint256[] memory scheduleRewards, - uint256 tau, VoteCoefficient memory voteCoef, uint256 _maxLocks, - address rewardsCalculator + address _rewardsContract ) external; + function initializeMainStream( + address _owner, + uint256[] memory scheduleTimes, + uint256[] memory scheduleRewards, + uint256 tau) external; + function proposeStream( address streamOwner, address rewardToken, diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 14f3f74..9b7c313 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -8,13 +8,12 @@ import "./StakingInternals.sol"; import "../StakingStorage.sol"; import "../interfaces/IStakingHandler.sol"; import "../vault/interfaces/IVault.sol"; -import "../../../common/security/ReentrancyGuard.sol"; import "../../../common/security/AdminPausable.sol"; // solhint-disable not-rely-on-time -contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, ReentrancyGuard, AdminPausable { +contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, AdminPausable { bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); - /** + /** * @dev initialize the contract and deploys the first stream of rewards * @dev initializable only once due to stakingInitialised flag * @notice By calling this function, the deployer of this contract must @@ -24,9 +23,6 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R * @param _mainToken token contract address * @param _weight Weighting coefficient for shares and penalties * @param _admin the owner and manager of the main token stream - * @param scheduleTimes init schedules times - * @param scheduleRewards init schedule rewards - * @param tau release time constant per stream */ function initializeStaking( address _admin, @@ -34,37 +30,40 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R address _mainToken, address _voteToken, Weight calldata _weight, - uint256[] memory scheduleTimes, - uint256[] memory scheduleRewards, - uint256 tau, VoteCoefficient memory voteCoef, uint256 _maxLocks, address _rewardsContract ) external override { rewardsCalculator = _rewardsContract; + _initializeStaking(_mainToken, _voteToken, _weight, _vault, _maxLocks, voteCoef.voteShareCoef, voteCoef.voteLockCoef); + require(IVault(vault).isSupportedToken(_mainToken), "Unsupported token"); + pausableInit(1, _admin); + _grantRole(STREAM_MANAGER_ROLE, _admin); + _grantRole(TREASURY_ROLE, _admin); + maxLockPeriod = ONE_YEAR; + } + + function initializeMainStream( + address _owner, + uint256[] memory scheduleTimes, + uint256[] memory scheduleRewards, + uint256 tau + ) external override onlyRole(STREAM_MANAGER_ROLE){ _validateStreamParameters( - _admin, - _mainToken, + _owner, + mainToken, scheduleRewards[MAIN_STREAM], scheduleRewards[MAIN_STREAM], scheduleTimes, scheduleRewards, tau ); - - _initializeStaking(_mainToken, _voteToken, _weight, _vault, _maxLocks, voteCoef.voteShareCoef, voteCoef.voteLockCoef); - require(IVault(vault).isSupportedToken(_mainToken), "Unsupported token"); - pausableInit(0, _admin); - - _grantRole(STREAM_MANAGER_ROLE, _admin); - _grantRole(TREASURY_ROLE, _admin); - uint256 streamId = 0; Schedule memory schedule = Schedule(scheduleTimes, scheduleRewards); streams.push( Stream({ - owner: _admin, - manager: _admin, + owner: _owner, + manager: _owner, rewardToken: mainToken, maxDepositAmount: 0, minDepositAmount: 0, @@ -76,10 +75,11 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R rps: 0 }) ); - maxLockPeriod = ONE_YEAR; - emit StreamProposed(streamId, _admin, mainToken, scheduleRewards[MAIN_STREAM]); - emit StreamCreated(streamId, _admin, mainToken, scheduleRewards[MAIN_STREAM]); - } + IVault(vault).deposit(msg.sender, mainToken, scheduleRewards[0]); + _adminPause(0); + emit StreamProposed(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); + emit StreamCreated(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); + } /** * @dev An admin of the staking contract can whitelist (propose) a stream. @@ -133,6 +133,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, R Stream storage stream = streams[streamId]; require(stream.status == StreamStatus.PROPOSED, "not proposed"); require(stream.schedule.time[0] >= block.timestamp, "prop expire"); + require(stream.owner == msg.sender, "bad owner"); require(rewardTokenAmount <= stream.maxDepositAmount, "rwrds high"); require(rewardTokenAmount >= stream.minDepositAmount, "rwrds low"); diff --git a/contracts/dao/staking/vault/interfaces/IVault.sol b/contracts/dao/staking/vault/interfaces/IVault.sol index 8b2d4bb..ef3ab73 100644 --- a/contracts/dao/staking/vault/interfaces/IVault.sol +++ b/contracts/dao/staking/vault/interfaces/IVault.sol @@ -3,7 +3,9 @@ pragma solidity 0.8.13; interface IVault { function initVault(address _admin,address[] calldata supportedTokens) external; - + + function deposit(address _user, address _token, uint256 _amount) external; + function addRewardsOperator(address _rewardsOperator) external; function addSupportedToken(address _token) external; @@ -11,7 +13,10 @@ interface IVault { function removeSupportedToken(address _token) external; function payRewards(address _user, address _token, uint256 _deposit) external; + + function emergencyStop() external; + + function emergencyWithdraw(address withdrawTo) external; function isSupportedToken(address token) external view returns (bool); - function deposit(address _user, address _token, uint256 _amount) external; } diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index c5bae0c..82190ce 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -15,7 +15,7 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { bytes32 public constant REWARDS_OPERATOR_ROLE = keccak256("REWARDS_OPERATOR_ROLE"); mapping(address => uint256) public deposited; mapping(address => bool) public override isSupportedToken; - + address[] public listOfSupportedTokens; function initVault(address _admin,address[] calldata supportedTokens) external override { require(!vaultInitialized, "Vault: Already Initialized"); @@ -33,12 +33,15 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { function payRewards(address _user, address _token, uint256 _amount) external override pausable(1){ require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "payRewards: No role"); require(isSupportedToken[_token], "Unsupported token"); + //require(deposited[_token] >= _amount,"payRewards: not enough deposit"); + // deposited[_token] -= _amount; IERC20(_token).safeTransfer(_user,_amount); } function deposit(address _user, address _token, uint256 _amount) external override pausable(1) { - require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "payRewards: No role"); + require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "deposit: No role"); require(isSupportedToken[_token], "Unsupported token"); + deposited[_token] += _amount; IERC20(_token).safeTransferFrom(_user, address(this),_amount); } @@ -55,12 +58,36 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { function removeSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) pausable(1) { require(isSupportedToken[_token], "Token does not exist"); isSupportedToken[_token] = false; + _removeToken(_token); emit TokenRemoved(_token, msg.sender, block.timestamp); } + function emergencyStop() external override onlyRole(DEFAULT_ADMIN_ROLE){ + _adminPause(1); + } + + function emergencyWithdraw(address withdrawTo) external override onlyRole(DEFAULT_ADMIN_ROLE){ + for(uint i = 0; i < listOfSupportedTokens.length;i++) + { + uint256 balance = IERC20(listOfSupportedTokens[i]).balanceOf(address(this)); + IERC20(listOfSupportedTokens[i]).safeTransfer(withdrawTo, balance); + } + } + function _addSupportedToken(address _token) internal { require(!isSupportedToken[_token], "Token already exists"); isSupportedToken[_token] = true; + listOfSupportedTokens.push(_token); emit TokenAdded(_token, msg.sender, block.timestamp); } + + function _removeToken(address _token) internal { + for(uint i = 0; i < listOfSupportedTokens.length; i++) { + if(listOfSupportedTokens[i] == _token){ + listOfSupportedTokens[i] = listOfSupportedTokens[listOfSupportedTokens.length -1]; + break; + } + } + listOfSupportedTokens.pop(); + } } diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 3766636..cf43a56 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -168,8 +168,9 @@ contract MultiSigWallet is IMultiSigWallet { bytes memory _data, uint _expireTimestamp ) public override onlyOwnerOrGov validateSubmitTxInputs(_to, _value, _data, _expireTimestamp) { + require(address(this).balance >= _value,"submitTransaction: not enough balance"); uint txIndex = transactions.length; - + transactions.push( Transaction({ to: _to, value: _value, data: _data, executed: false, numConfirmations: 0, expireTimestamp: _expireTimestamp }) ); diff --git a/scripts/migrations/test/2_deploy_init_staking_proxy.js b/scripts/migrations/test/2_deploy_init_staking_proxy.js index 440b26b..deb93c3 100644 --- a/scripts/migrations/test/2_deploy_init_staking_proxy.js +++ b/scripts/migrations/test/2_deploy_init_staking_proxy.js @@ -125,18 +125,6 @@ module.exports = async function(deployer) { {"type": "uint32", "name":"penaltyWeightMultiplier"} ] }, - { - type: 'uint256[]', - name: 'scheduleTimes' - }, - { - type: 'uint256[]', - name: 'scheduleRewards' - }, - { - type: 'uint256', - name: 'tau' - }, { type: 'tuple', name: 'VoteCoefficient', @@ -154,11 +142,12 @@ module.exports = async function(deployer) { name: '_rewardsContract' }] }, [MultiSigWallet.address, vaultService.address, MainToken.address, VMainToken.address, - weightObject, scheduleTimes, scheduleRewards, tau, - voteObject, maxNumberOfLocks, RewardsCalculator.address]); + weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address]); await deployer.deploy(StakingProxyAdmin, {gas:8000000}); await deployer.deploy(StakingProxy, StakingPackage.address, StakingProxyAdmin.address, toInitialize, {gas:8000000}); + + } catch(error) { console.log(error) } diff --git a/scripts/migrations/test/3_add_vault_operator.js b/scripts/migrations/test/3_add_vault_operator.js index cd2aea8..93c829e 100644 --- a/scripts/migrations/test/3_add_vault_operator.js +++ b/scripts/migrations/test/3_add_vault_operator.js @@ -1,15 +1,11 @@ const eventsHelper = require("../../tests/helpers/eventsHelper"); -const IVault = artifacts.require('./dao/staking/vault/interfaces/IVault.sol'); -const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); -const IERC20 = artifacts.require("./dao/tokens/ERC20/IERC20.sol"); const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const T_TO_TRANSFER = web3.utils.toWei('20000', 'ether'); const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') diff --git a/scripts/migrations/test/6_setup_vault_tokens.js b/scripts/migrations/test/6_setup_vault_tokens.js index 5561d68..3e933be 100644 --- a/scripts/migrations/test/6_setup_vault_tokens.js +++ b/scripts/migrations/test/6_setup_vault_tokens.js @@ -1,25 +1,26 @@ const eventsHelper = require("../../tests/helpers/eventsHelper"); -const IVault = artifacts.require('./dao/staking/vault/interfaces/IVault.sol'); -const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); -const IERC20 = artifacts.require("./dao/tokens/ERC20/IERC20.sol"); - const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; - -const T_TO_TRANSFER = web3.utils.toWei('20000', 'ether'); +const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') +const blockchain = require("../../tests/helpers/blockchain"); +const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') +//TODO: Do it in prod script +const _getTimeStamp = async () => { + const timestamp = await blockchain.getLatestBlockTimestamp(); + return timestamp; +} - -const _encodeTransferFunction = (_account, _amount) => { +const _encodeApproveFunction = (_account, _amount) => { let toRet = web3.eth.abi.encodeFunctionCall({ - name: 'transfer', + name: 'approve', type: 'function', inputs: [{ type: 'address', - name: 'to' + name: 'spender' },{ type: 'uint256', name: 'amount' @@ -29,18 +30,77 @@ const _encodeTransferFunction = (_account, _amount) => { return toRet; } +const _encodeInitMainStreamFunction = (_owner, _scheduleTimes, _scheduleRewards, tau) => { + let toInitializeMainStream = web3.eth.abi.encodeFunctionCall({ + name: 'initializeMainStream', + type: 'function', + inputs: [{ + type: 'address', + name: '_owner' + }, + { + type: 'uint256[]', + name: 'scheduleTimes' + }, + { + type: 'uint256[]', + name: 'scheduleRewards' + }, + { + type: 'uint256', + name: 'tau' + }] + }, [MultiSigWallet.address, _scheduleTimes, _scheduleRewards, tau]); + + return toInitializeMainStream +} + +const tau = 2; + module.exports = async function(deployer) { - const vaultService = await IVault.at(VaultProxy.address) + + const startTime = await _getTimeStamp() + 3 * 24 * 60 * 60; + const oneYear = 31556926; + const scheduleTimes = [ + startTime, + startTime + oneYear, + startTime + 2 * oneYear, + startTime + 3 * oneYear, + startTime + 4 * oneYear, + ]; + + const scheduleRewards = [ + web3.utils.toWei('20000', 'ether'), + web3.utils.toWei('10000', 'ether'), + web3.utils.toWei('5000', 'ether'), + web3.utils.toWei('2500', 'ether'), + web3.utils.toWei("0", 'ether') + ]; + + const multiSigWallet = await IMultiSigWallet.at(MultiSigWallet.address) - let result = await multiSigWallet.submitTransaction( - MainToken.address, + + let resultApprove = await multiSigWallet.submitTransaction( + MainToken.address, + EMPTY_BYTES, + _encodeApproveFunction(VaultProxy.address,scheduleRewards[0]), + 0, + {gas: 8000000} + ) + + let txIndexApprove = eventsHelper.getIndexedEventArgs(resultApprove, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(txIndexApprove, {gas: 8000000}); + await multiSigWallet.executeTransaction(txIndexApprove, {gas: 8000000}); + + let resultInit = await multiSigWallet.submitTransaction( + StakingProxy.address, EMPTY_BYTES, - _encodeTransferFunction(vaultService.address, T_TO_TRANSFER), + _encodeInitMainStreamFunction(MultiSigWallet.address,scheduleTimes, scheduleRewards,tau), 0, {gas: 8000000} ); - let txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; - await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); - await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); + let txIndexInit = eventsHelper.getIndexedEventArgs(resultInit, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(txIndexInit, {gas: 8000000}); + await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); } From baa297e31447b2ffb62ad62d208b1cb6a245db3f Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 29 Dec 2022 17:07:26 +0545 Subject: [PATCH 14/77] tests passing for other round of audit fixes --- audit-report/Fathom_DAO.md | 14 ++++---- contracts/common/security/AdminPausable.sol | 2 +- contracts/dao/governance/Governor.sol | 13 ++++++-- contracts/dao/staking/StakingStorage.sol | 6 ++-- contracts/dao/staking/StakingStructs.sol | 1 + .../dao/staking/packages/StakingHandler.sol | 33 ++++++------------- .../dao/staking/packages/StakingInternals.sol | 5 +++ .../staking/vault/packages/VaultPackage.sol | 7 +++- scripts/tests/dao/staking/staking.test.js | 2 +- 9 files changed, 46 insertions(+), 37 deletions(-) diff --git a/audit-report/Fathom_DAO.md b/audit-report/Fathom_DAO.md index 806c75d..9ce7c9e 100644 --- a/audit-report/Fathom_DAO.md +++ b/audit-report/Fathom_DAO.md @@ -176,7 +176,7 @@ We recommend discarding the `updateConfig` function and consider mechanisms for ### MAJOR -#### [NEW] In `MultiSigWallet` there's no parameter defining minimum amount of signatures[NOTDONE but would have bad impact on test, MAX] +#### [NEW] In `MultiSigWallet` there's no parameter defining minimum amount of signatures[NOTDONE but would have bad impact on test, MAXJI] -> Minimum = 1 set ##### Description The parameter [`_numConfirmationsRequired`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L77) is checked in the constructor and in the function [`changeRequirement`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L116), that is not equal to `0`, however, when multi-signature is set, it allows the value `1`, and the contract may be used by one of the `owners`. @@ -210,7 +210,7 @@ In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contract We recommend adding the `updateMultisig` function, but so that only the old `multisig` could call it. -#### [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE, how to do? ask more feedback, MAX] +#### [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE, how to do? ask more feedback, MAXJI] ##### Description There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. ##### Recommendation @@ -242,7 +242,7 @@ This creates a risk that if `MINTER_ROLE` is compromised by an attacker, the adm We recommend adding separate functions to grant and revoke the `MINTER_ROLE`, which will also add and remove addresses from the `isWhitelisted` list. -#### [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[ASK MAX about targets] +#### [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[ASK MAX JI about targets] ##### Description In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. ##### Recommendation @@ -258,7 +258,7 @@ The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contrac ##### Recommendation We recommend adding the `emergencyExit` function in the contract which permanently blocks contract function calls for `REWARD_OPERATOR_ROLE`, and adding the `migrate` function, which allows to move tokens and token balances to a new version of `VaultPackage`. -#### [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[DONE, please explain more] +#### [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE, please explain more] ##### Description In the `StakingHandlers` contract, calling the function [`updateVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L269) can cause all contract functions that work with balances and `VaultPackage` functions to be blocked. ##### Recommendation @@ -572,7 +572,7 @@ ProposalState status = state(proposalId); require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); ``` -#### [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[NOTDONE] +#### [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[Ask ANton,MAXJI] ##### Description In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) contracts the `execute` functions do not check the `msg.value` balance value needed to execute `_targets`, which would result in gas consumption even if the amount of `ETH` is not enough. ##### Recommendation @@ -613,7 +613,7 @@ In the `VaultPackage` contract when calling the function [`payRewards`](https:// We recommend adding a check that tokens are on the balance and that `amount != 0`, and return error using `custom errors` (`revert CustomError`) or with `require`. -#### [NEW] There is no limit on the maximum number of active `streams` in the `StakingHandlers` contract[NOTDONE] +#### [NEW] There is no limit on the maximum number of active `streams` in the `StakingHandlers` contract[NOTNEEDED] ##### Description In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) contract there is no limit on the maximum number of active `streams`. This creates a situation of an uncontrolled gas consumption when dealing with contract functions and can lead to DoS. ##### Recommendation @@ -658,7 +658,7 @@ We recommend to use [`muldiv`](https://xn--2-umb.com/21/muldiv/index.html) to mu We also recommend to update `voteLockCoef` [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L42) and add checks that it is not zero (to prevent division by zero) and that it is not too big in order to avoid overflow in `BoringMath`. -#### [NEW] Multiple `streams` can be active at the same time with the same parameters in `StakingHandler.sol `[] +#### [NEW] Multiple `streams` can be active at the same time with the same parameters in `StakingHandler.sol `[NOTDONE] ##### Description In the contract [StakingHandler]( diff --git a/contracts/common/security/AdminPausable.sol b/contracts/common/security/AdminPausable.sol index c5e4831..cd9ea24 100644 --- a/contracts/common/security/AdminPausable.sol +++ b/contracts/common/security/AdminPausable.sol @@ -29,7 +29,7 @@ contract AdminPausable is IAdminPausable, AccessControlUpgradeable { paused = flags; } - function pausableInit(uint256 _flags, address _admin) internal initializer { + function pausableInit(uint256 _flags, address _admin) internal onlyInitializing { __AccessControl_init_unchained(); _grantRole(DEFAULT_ADMIN_ROLE, _admin); _grantRole(PAUSE_ROLE, _admin); diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index c9b343f..aaf1e3a 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -90,15 +90,24 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { ProposalState status = state(proposalId); require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); - + //ASK MAX JI: + uint256 totalValue = 0; + for (uint256 i = 0;i < values.length; i++){ + totalValue += values[i]; + } + require(msg.value >= totalValue, "execute: msg.value not sufficient"); _proposals[proposalId].executed = true; + emit ProposalExecuted(proposalId); _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); _execute(proposalId, targets, values, calldatas, descriptionHash); _afterExecute(proposalId, targets, values, calldatas, descriptionHash); - + if(msg.value > totalValue){ + (bool sent, ) = msg.sender.call{value: (msg.value - totalValue)}(""); + require(sent, "Failed to send ether"); + } return proposalId; } diff --git a/contracts/dao/staking/StakingStorage.sol b/contracts/dao/staking/StakingStorage.sol index 90949dc..f4ba7c2 100644 --- a/contracts/dao/staking/StakingStorage.sol +++ b/contracts/dao/staking/StakingStorage.sol @@ -49,8 +49,10 @@ contract StakingStorage { mapping(address => User) public users; Stream[] internal streams; - + + uint256 internal maxOnBehalfLockPositions; ///Mapping (user => LockedBalance) to keep locking information for each user mapping(address => LockedBalance[]) internal locks; - mapping(uint256 => uint256) public streamTotalUserPendings; + mapping(uint256 => uint256) public streamTotalUserPendings; + mapping(address => uint256) internal nOnBehalfLocks; } diff --git a/contracts/dao/staking/StakingStructs.sol b/contracts/dao/staking/StakingStructs.sol index feb3e09..1ff87e2 100644 --- a/contracts/dao/staking/StakingStructs.sol +++ b/contracts/dao/staking/StakingStructs.sol @@ -49,6 +49,7 @@ struct LockedBalance { uint128 amountOfVoteToken; uint128 positionStreamShares; uint64 end; + bool onBehalf; address owner; } struct Stream { diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 9b7c313..75e2ada 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -13,7 +13,10 @@ import "../../../common/security/AdminPausable.sol"; contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, AdminPausable { bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); - /** + constructor(){ + _disableInitializers(); + } + /** * @dev initialize the contract and deploys the first stream of rewards * @dev initializable only once due to stakingInitialised flag * @notice By calling this function, the deployer of this contract must @@ -33,7 +36,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A VoteCoefficient memory voteCoef, uint256 _maxLocks, address _rewardsContract - ) external override { + ) external override initializer{ rewardsCalculator = _rewardsContract; _initializeStaking(_mainToken, _voteToken, _weight, _vault, _maxLocks, voteCoef.voteShareCoef, voteCoef.voteLockCoef); require(IVault(vault).isSupportedToken(_mainToken), "Unsupported token"); @@ -185,7 +188,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _createLock(amount, lockPeriod, account); } - function unlock(uint256 lockId) public override pausable(1) { + function unlock(uint256 lockId) public override { _verifyUnlock(lockId); LockedBalance storage lock = locks[msg.sender][lockId - 1]; require(lock.end <= block.timestamp, "lock not open"); @@ -255,24 +258,6 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } } - function updateConfig( - Weight memory _weight, - address _voteToken, - address _rewardsCalculator, - VoteCoefficient memory _voteCoef, - uint256 _maxLockPeriod, - uint256 _maxLockPositions - ) public onlyRole(DEFAULT_ADMIN_ROLE) { - weight = _weight; - voteToken = _voteToken; - rewardsCalculator = _rewardsCalculator; - voteShareCoef = _voteCoef.voteShareCoef; - voteLockCoef = _voteCoef.voteLockCoef; - maxLockPeriod = _maxLockPeriod; - maxLockPositions = _maxLockPositions; - } - - function updateVault(address _vault) public override onlyRole(DEFAULT_ADMIN_ROLE) { // enforce pausing this contract before updating the address. // This mitigates the risk of future invalid reward claims @@ -296,12 +281,14 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A IERC20(mainToken).transferFrom(msg.sender, address(vault), amount); } - function _verifyUnlock(uint256 lockId) internal view { + function _verifyUnlock(uint256 lockId) internal { require(lockId > 0, "zero lockid"); require(lockId <= locks[msg.sender].length, "bad lockid"); LockedBalance storage lock = locks[msg.sender][lockId - 1]; require(lock.amountOfToken > 0, "no lock amount"); require(lock.owner == msg.sender, "bad owner"); + if(lock.onBehalf == true && nOnBehalfLocks[msg.sender] >0){ + nOnBehalfLocks[msg.sender] -= 1; + } } - } diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 090aeef..791d7ce 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -48,8 +48,13 @@ contract StakingInternals is StakingStorage, RewardsInternals { userAccount.voteTokenBalance += BoringMath.to128(nVoteToken); totalAmountOfVoteToken += nVoteToken; } + if(account != msg.sender){ + require(nOnBehalfLocks[account] <= maxOnBehalfLockPositions,"max lock on behalf"); + nOnBehalfLocks[account]+=1; + } LockedBalance memory _newLock = LockedBalance({ amountOfToken: BoringMath.to128(amount), + onBehalf: true ? msg.sender != account : false, amountOfVoteToken: BoringMath.to128(nVoteToken), positionStreamShares: 0, end: BoringMath.to64(lockPeriod + block.timestamp), diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index 82190ce..333f7f5 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -17,7 +17,10 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { mapping(address => bool) public override isSupportedToken; address[] public listOfSupportedTokens; - function initVault(address _admin,address[] calldata supportedTokens) external override { + constructor() { + _disableInitializers(); + } + function initVault(address _admin,address[] calldata supportedTokens) initializer external override { require(!vaultInitialized, "Vault: Already Initialized"); vaultInitialized = true; for (uint i = 0; i < supportedTokens.length; i++) { @@ -67,6 +70,8 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { } function emergencyWithdraw(address withdrawTo) external override onlyRole(DEFAULT_ADMIN_ROLE){ + require(paused != 0, "required pause"); + require(withdrawTo != address(0),"withdrawTo: Zero addr"); for(uint i = 0; i < listOfSupportedTokens.length;i++) { uint256 balance = IERC20(listOfSupportedTokens[i]).balanceOf(address(this)); diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index 2af2c22..20650cc 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -1257,7 +1257,7 @@ describe("Staking Test", () => { it('Should not be initalizable twice - Vault', async() => { - const errorMessage = "Vault: Already Initialized"; + const errorMessage = "Initializable: contract is already initialized"; await shouldRevert( vaultService.initVault(multiSigWallet.address,[FTHMToken.address], {gas: 8000000}), errTypes.revert, From 302df3a7da6a88e8be256d53bfb075442c332b36 Mon Sep 17 00:00:00 2001 From: ssubik Date: Fri, 30 Dec 2022 19:26:29 +0545 Subject: [PATCH 15/77] doing audit fixes --- audit-report/Fathom_DAO.md | 8 +++--- .../dao/governance/MainTokenGovernor.sol | 6 ++-- .../dao/staking/interfaces/IStakingGetter.sol | 4 +-- .../dao/staking/packages/StakingGetters.sol | 8 ------ .../dao/staking/packages/StakingHandler.sol | 28 +++++++++++++++---- .../dao/staking/packages/StakingInternals.sol | 4 +-- .../dao/staking/vault/interfaces/IVault.sol | 4 ++- .../staking/vault/packages/VaultPackage.sol | 17 +++++++---- 8 files changed, 48 insertions(+), 31 deletions(-) diff --git a/audit-report/Fathom_DAO.md b/audit-report/Fathom_DAO.md index 9ce7c9e..4a1333b 100644 --- a/audit-report/Fathom_DAO.md +++ b/audit-report/Fathom_DAO.md @@ -163,7 +163,7 @@ In the `StakingHandler` contract the [`withdrawAllStreams`](https://github.com/I We recommend adding to the `withdrawAllStreams` and `withdrawStream` functions a check that the output from `stream` has the status `ACTIVE`. -#### [NEW] Calling the `updateConfig` function may block the work of the `StakingHandlers` contract[NOTDONE,Ask Anton, just remove updateConfig?] +#### [NEW] Calling the `updateConfig` function may block the work of the `StakingHandlers` contract[Could you clarify this more? What does migration actually mean, upgrade or moving to completely new contract address?,Ask Anton, just remove updateConfig?] ##### Description Calling the function [`updateConfig`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L252) in the `StakingHandler` contract can disrupt its work. This is possible for the following reasons: @@ -176,7 +176,7 @@ We recommend discarding the `updateConfig` function and consider mechanisms for ### MAJOR -#### [NEW] In `MultiSigWallet` there's no parameter defining minimum amount of signatures[NOTDONE but would have bad impact on test, MAXJI] -> Minimum = 1 set +#### [NEW] In `MultiSigWallet` there's no parameter defining minimum amount of signatures[NOTDONE but would have bad impact on test, MAXJI] -> DONE ##### Description The parameter [`_numConfirmationsRequired`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L77) is checked in the constructor and in the function [`changeRequirement`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L116), that is not equal to `0`, however, when multi-signature is set, it allows the value `1`, and the contract may be used by one of the `owners`. @@ -242,7 +242,7 @@ This creates a risk that if `MINTER_ROLE` is compromised by an attacker, the adm We recommend adding separate functions to grant and revoke the `MINTER_ROLE`, which will also add and remove addresses from the `isWhitelisted` list. -#### [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[ASK MAX JI about targets] +#### [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[ASK MAXJI about targets] ##### Description In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. ##### Recommendation @@ -596,7 +596,7 @@ In the [`_setProposalThreshold`](https://github.com/Into-the-Fathom/fathom-dao-s ##### Recommendation We recommend adding a check that `newProposalThreshold` is not zero. -#### [NEW] There is no limit on the number of proposals for one proposer in `Governor`[Ask MAX] +#### [NEW] There is no limit on the number of proposals for one proposer in `Governor`[Ask MAXJI] ##### Description In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. ##### Recommendation diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index 262a886..c4ad7d9 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -81,17 +81,17 @@ contract MainTokenGovernor is } function addSupportingToken(address _token) public onlyGovernance { - require(!isSupportedToken[_token], "Token already exists"); + require(!isSupportedToken[_token], "Token already supported"); isSupportedToken[_token] = true; } function removeSupportingToken(address _token) public onlyGovernance { - require(isSupportedToken[_token], "Token does not exist"); + require(isSupportedToken[_token], "Token is not supported"); isSupportedToken[_token] = false; } function withdrawToken(address _token, address _withdrawTo) public onlyMultiSig { - require(isSupportedToken[_token],"Token does not exist"); + require(isSupportedToken[_token],"Token is not supported"); uint256 balance = IERC20(_token).balanceOf(address(this)); IERC20(_token).safeTransfer(_withdrawTo, balance); } diff --git a/contracts/dao/staking/interfaces/IStakingGetter.sol b/contracts/dao/staking/interfaces/IStakingGetter.sol index 4ebd4dc..6dada23 100644 --- a/contracts/dao/staking/interfaces/IStakingGetter.sol +++ b/contracts/dao/staking/interfaces/IStakingGetter.sol @@ -30,9 +30,9 @@ interface IStakingGetter { function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); - function getStreamsCount() external view returns (uint256); + // function getStreamsCount() external view returns (uint256); - function getLatestRewardsPerShare(uint256 streamId) external view returns (uint256); + // function getLatestRewardsPerShare(uint256 streamId) external view returns (uint256); function getWeight() external view returns (Weight memory); } diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index a11bf91..af9708c 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -62,14 +62,6 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { return (streams[streamId].schedule.time, streams[streamId].schedule.reward); } - function getStreamsCount() external view override returns (uint256) { - return streams.length; - } - - function getLatestRewardsPerShare(uint256 streamId) external view override returns (uint256) { - return _getLatestRewardsPerShare(streamId); - } - function getWeight() external view override returns (Weight memory) { return weight; } diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 75e2ada..bf41a29 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -216,17 +216,18 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _earlyUnlock(lockId, msg.sender); prohibitedEarlyWithdraw[msg.sender][lockId] = false; } + function claimRewards(uint256 streamId, uint256 lockId) public override pausable(1) { require(lockId <= locks[msg.sender].length, "bad lockid"); - require(lockId != 0, "lockId cant be zero"); + require(lockId != 0, "lockId zero"); _updateStreamRPS(); _moveRewardsToPending(msg.sender, streamId, lockId); } function claimAllStreamRewardsForLock(uint256 lockId) public override pausable(1) { require(lockId <= locks[msg.sender].length, "bad lockid"); - require(lockId != 0, "lockId cant be zero"); + require(lockId != 0, "lockId zero"); _updateStreamRPS(); // Claim all streams while skipping inactive streams. _moveAllStreamRewardsToPending(msg.sender, lockId); @@ -241,7 +242,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A User storage userAccount = users[msg.sender]; require(userAccount.pendings[streamId] != 0, "no pendings"); require(block.timestamp > userAccount.releaseTime[streamId], "not released"); - require(streams[streamId].status == StreamStatus.ACTIVE,"stream not active"); + require(streams[streamId].status == StreamStatus.ACTIVE,"stream nt active"); _withdraw(streamId); } @@ -258,12 +259,27 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } } + /** + * @dev Disregard rewards for emergency unlock and withdraw + */ + function emergencyUnlockAndWithdraw() public { + require(paused != 0,"nt emergency"); + uint256 numberOfLocks = locks[msg.sender].length; + for(uint i = 0;i <= numberOfLocks;i++){ + LockedBalance storage lock = locks[msg.sender][i]; + uint256 stakeValue = lock.amountOfToken; + _unlock(stakeValue, stakeValue, i+1, msg.sender); + } + _withdraw(MAIN_STREAM); + } + + function updateVault(address _vault) public override onlyRole(DEFAULT_ADMIN_ROLE) { // enforce pausing this contract before updating the address. // This mitigates the risk of future invalid reward claims require(paused != 0, "required pause"); require(_vault != address(0), "zero addr"); - require(_vault != vault, "same addr"); + require(IVault(vault).migrated(),"nt migrated"); vault = _vault; } @@ -275,7 +291,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function _createLock(uint256 amount, uint256 lockPeriod, address account) internal { require(locks[account].length <= maxLockPositions, "max locks"); require(amount > 0, "amount 0"); - require(lockPeriod <= maxLockPeriod, "max lock period"); + require(lockPeriod <= maxLockPeriod, "max time"); _updateStreamRPS(); _lock(account, amount, lockPeriod); IERC20(mainToken).transferFrom(msg.sender, address(vault), amount); @@ -285,7 +301,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A require(lockId > 0, "zero lockid"); require(lockId <= locks[msg.sender].length, "bad lockid"); LockedBalance storage lock = locks[msg.sender][lockId - 1]; - require(lock.amountOfToken > 0, "no lock amount"); + require(lock.amountOfToken > 0, "no amount"); require(lock.owner == msg.sender, "bad owner"); if(lock.onBehalf == true && nOnBehalfLocks[msg.sender] >0){ nOnBehalfLocks[msg.sender] -= 1; diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 791d7ce..bb401be 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -29,7 +29,8 @@ contract StakingInternals is StakingStorage, RewardsInternals { require(_weight.maxWeightShares > _weight.minWeightShares, "bad share"); require(_weight.maxWeightPenalty > _weight.minWeightPenalty, "bad penalty"); - require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "Wrong penalty weight"); + require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "wrong weight"); + mainToken = _mainToken; voteToken = _voteToken; weight = _weight; @@ -44,7 +45,6 @@ contract StakingInternals is StakingStorage, RewardsInternals { User storage userAccount = users[account]; if (lockPeriod > 0) { nVoteToken = (amount * lockPeriod * POINT_MULTIPLIER) / voteLockCoef / POINT_MULTIPLIER; //maxVoteTokens; - userAccount.voteTokenBalance += BoringMath.to128(nVoteToken); totalAmountOfVoteToken += nVoteToken; } diff --git a/contracts/dao/staking/vault/interfaces/IVault.sol b/contracts/dao/staking/vault/interfaces/IVault.sol index ef3ab73..471963e 100644 --- a/contracts/dao/staking/vault/interfaces/IVault.sol +++ b/contracts/dao/staking/vault/interfaces/IVault.sol @@ -16,7 +16,9 @@ interface IVault { function emergencyStop() external; - function emergencyWithdraw(address withdrawTo) external; + function migrate(address vaultPackageMigrateTo) external; function isSupportedToken(address token) external view returns (bool); + + function migrated() external view returns(bool); } diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index 333f7f5..9f89f09 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -16,6 +16,7 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { mapping(address => uint256) public deposited; mapping(address => bool) public override isSupportedToken; address[] public listOfSupportedTokens; + bool public override migrated; constructor() { _disableInitializers(); @@ -36,6 +37,8 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { function payRewards(address _user, address _token, uint256 _amount) external override pausable(1){ require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "payRewards: No role"); require(isSupportedToken[_token], "Unsupported token"); + require(_amount!=0,"amount zero"); + require(IERC20(_token).balanceOf(address(this))>=_amount,"not enough balance"); //require(deposited[_token] >= _amount,"payRewards: not enough deposit"); // deposited[_token] -= _amount; IERC20(_token).safeTransfer(_user,_amount); @@ -65,18 +68,22 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { emit TokenRemoved(_token, msg.sender, block.timestamp); } - function emergencyStop() external override onlyRole(DEFAULT_ADMIN_ROLE){ + function emergencyStop() external override { _adminPause(1); } - function emergencyWithdraw(address withdrawTo) external override onlyRole(DEFAULT_ADMIN_ROLE){ + function migrate(address newVaultPackage) external override onlyRole(DEFAULT_ADMIN_ROLE){ + require(!migrated,"vault already migrated"); require(paused != 0, "required pause"); - require(withdrawTo != address(0),"withdrawTo: Zero addr"); + require(newVaultPackage != address(0),"withdrawTo: Zero addr"); for(uint i = 0; i < listOfSupportedTokens.length;i++) { - uint256 balance = IERC20(listOfSupportedTokens[i]).balanceOf(address(this)); - IERC20(listOfSupportedTokens[i]).safeTransfer(withdrawTo, balance); + address token = listOfSupportedTokens[i]; + uint256 balance = IERC20(token).balanceOf(address(this)); + IERC20(token).safeApprove(newVaultPackage,balance); + IVault(newVaultPackage).deposit(address(this), listOfSupportedTokens[i],balance); } + migrated = true; } function _addSupportedToken(address _token) internal { From 9199dbbd0a3ab35d00645835b6ceb99fda9400d2 Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 2 Jan 2023 16:54:03 +0545 Subject: [PATCH 16/77] finalizing audit fixes --- contracts/dao/governance/Governor.sol | 3 -- .../staking/interfaces/IStakingHandler.sol | 4 ++- .../dao/staking/packages/StakingHandler.sol | 14 ++++---- .../dao/staking/packages/StakingInternals.sol | 2 +- .../staking/vault/packages/VaultPackage.sol | 5 +-- contracts/dao/tokens/VMainToken.sol | 1 - contracts/dao/treasury/MultiSigWallet.sol | 4 +++ .../test/2_deploy_init_staking_proxy.js | 8 +++-- scripts/tests/dao/demo/staking.demo.test.js | 9 ++--- scripts/tests/dao/full-flow-demo.test.js | 6 ++-- .../dao/governance/proposal-flow.test.js | 4 +-- .../token-creation-though-gov.test.js | 2 +- scripts/tests/dao/staking/staking.test.js | 36 ++++++++++++++++--- 13 files changed, 67 insertions(+), 31 deletions(-) diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index aaf1e3a..8ab32cc 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -29,7 +29,6 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); - //AuditFix There is no validation for `maxTargets` when executing in `Governor` - ASK THIS, to make it modifiable uint256 public maxTargets; string private _name; uint256[] private proposalIds; @@ -90,7 +89,6 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { ProposalState status = state(proposalId); require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); - //ASK MAX JI: uint256 totalValue = 0; for (uint256 i = 0;i < values.length; i++){ totalValue += values[i]; @@ -202,7 +200,6 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { emit RevokeConfirmation(msg.sender, _proposalId); } - //AuditFix There is no possibility to update `multisig` in `Governor function updateMultiSig(address newMultiSig) public onlyMultiSig { require(newMultiSig != address(0), "updateMultiSig: newMultiSig cant be set to zero address"); emit MultiSigUpdated(newMultiSig, multiSig); diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index 9878392..8b455d4 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -15,7 +15,8 @@ interface IStakingHandler { Weight calldata _weight, VoteCoefficient memory voteCoef, uint256 _maxLocks, - address _rewardsContract + address _rewardsContract, + uint256 _maxOnBehalfLockPositions ) external; function initializeMainStream( @@ -63,4 +64,5 @@ interface IStakingHandler { function withdrawPenalty(address penaltyReceiver) external; function updateVault(address _vault) external; + function emergencyUnlockAndWithdraw() external; } diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index bf41a29..1bed169 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -35,7 +35,8 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A Weight calldata _weight, VoteCoefficient memory voteCoef, uint256 _maxLocks, - address _rewardsContract + address _rewardsContract, + uint256 _maxOnBehalfLockPositions ) external override initializer{ rewardsCalculator = _rewardsContract; _initializeStaking(_mainToken, _voteToken, _weight, _vault, _maxLocks, voteCoef.voteShareCoef, voteCoef.voteLockCoef); @@ -44,6 +45,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _grantRole(STREAM_MANAGER_ROLE, _admin); _grantRole(TREASURY_ROLE, _admin); maxLockPeriod = ONE_YEAR; + maxOnBehalfLockPositions = _maxOnBehalfLockPositions; } function initializeMainStream( @@ -262,13 +264,13 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A /** * @dev Disregard rewards for emergency unlock and withdraw */ - function emergencyUnlockAndWithdraw() public { + function emergencyUnlockAndWithdraw() public override{ require(paused != 0,"nt emergency"); uint256 numberOfLocks = locks[msg.sender].length; - for(uint i = 0;i <= numberOfLocks;i++){ - LockedBalance storage lock = locks[msg.sender][i]; + for(uint lockId = 1;lockId <= numberOfLocks;lockId++){ + LockedBalance storage lock = locks[msg.sender][lockId]; uint256 stakeValue = lock.amountOfToken; - _unlock(stakeValue, stakeValue, i+1, msg.sender); + _unlock(stakeValue, stakeValue, lockId, msg.sender); } _withdraw(MAIN_STREAM); } @@ -294,7 +296,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A require(lockPeriod <= maxLockPeriod, "max time"); _updateStreamRPS(); _lock(account, amount, lockPeriod); - IERC20(mainToken).transferFrom(msg.sender, address(vault), amount); + IVault(vault).deposit(msg.sender, mainToken, amount); } function _verifyUnlock(uint256 lockId) internal { diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index bb401be..6c6872f 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -49,7 +49,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { totalAmountOfVoteToken += nVoteToken; } if(account != msg.sender){ - require(nOnBehalfLocks[account] <= maxOnBehalfLockPositions,"max lock on behalf"); + require(nOnBehalfLocks[account] < maxOnBehalfLockPositions,"max lock on behalf"); nOnBehalfLocks[account]+=1; } LockedBalance memory _newLock = LockedBalance({ diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index 9f89f09..e3f0fdc 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -39,8 +39,8 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { require(isSupportedToken[_token], "Unsupported token"); require(_amount!=0,"amount zero"); require(IERC20(_token).balanceOf(address(this))>=_amount,"not enough balance"); - //require(deposited[_token] >= _amount,"payRewards: not enough deposit"); - // deposited[_token] -= _amount; + require(deposited[_token] >= _amount,"payRewards: not enough deposit"); + deposited[_token] -= _amount; IERC20(_token).safeTransfer(_user,_amount); } @@ -63,6 +63,7 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { /// @param _token stream ERC20 token address function removeSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) pausable(1) { require(isSupportedToken[_token], "Token does not exist"); + require(deposited[_token] == 0,"Token is still in use"); isSupportedToken[_token] = false; _removeToken(_token); emit TokenRemoved(_token, msg.sender, block.timestamp); diff --git a/contracts/dao/tokens/VMainToken.sol b/contracts/dao/tokens/VMainToken.sol index 7a8abd1..a8a0c42 100644 --- a/contracts/dao/tokens/VMainToken.sol +++ b/contracts/dao/tokens/VMainToken.sol @@ -45,7 +45,6 @@ contract VMainToken is IVMainToken, Pausable, AccessControl, Initializable, ERC2 isWhiteListed[_toRemove] = false; emit MemberRemovedFromWhitelist(_toRemove); } - //AuditFix When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update function grantMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)){ _grantRole(MINTER_ROLE, _minter); addToWhitelist(_minter); diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index cf43a56..d77b055 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -169,6 +169,10 @@ contract MultiSigWallet is IMultiSigWallet { uint _expireTimestamp ) public override onlyOwnerOrGov validateSubmitTxInputs(_to, _value, _data, _expireTimestamp) { require(address(this).balance >= _value,"submitTransaction: not enough balance"); + if(!_to.isContract()){ + require(_value!= 0, "submitTransaction: value is zero"); + require(_data.length >0,"submitTransaction: not equal"); + } uint txIndex = transactions.length; transactions.push( diff --git a/scripts/migrations/test/2_deploy_init_staking_proxy.js b/scripts/migrations/test/2_deploy_init_staking_proxy.js index deb93c3..97c5caa 100644 --- a/scripts/migrations/test/2_deploy_init_staking_proxy.js +++ b/scripts/migrations/test/2_deploy_init_staking_proxy.js @@ -53,7 +53,7 @@ const maxWeightPenalty = 3000; const minWeightPenalty = 100; const weightMultiplier = 10; const maxNumberOfLocks = 10; - +const maxOnBehalfLockPositions = 2; const tau = 2; const lockingVoteWeight = 365 * 24 * 60 * 60; @@ -140,9 +140,13 @@ module.exports = async function(deployer) { { type: 'address', name: '_rewardsContract' + }, + { + type: 'uint256', + name: '_maxOnBehalfLockPositions' }] }, [MultiSigWallet.address, vaultService.address, MainToken.address, VMainToken.address, - weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address]); + weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address,maxOnBehalfLockPositions]); await deployer.deploy(StakingProxyAdmin, {gas:8000000}); await deployer.deploy(StakingProxy, StakingPackage.address, StakingProxyAdmin.address, toInitialize, {gas:8000000}); diff --git a/scripts/tests/dao/demo/staking.demo.test.js b/scripts/tests/dao/demo/staking.demo.test.js index 3f73c1d..4062ae7 100644 --- a/scripts/tests/dao/demo/staking.demo.test.js +++ b/scripts/tests/dao/demo/staking.demo.test.js @@ -307,7 +307,7 @@ describe("Staking Test and Upgrade Test", () => { expectedTotalAmountOfVFTHM = new web3.utils.BN(0) it('Should create a lock possition with lockId = 1 for staker_1', async() => { // So that staker 1 can actually stake the token: - await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_1}) + await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_1}) const beforeFTHMBalance = await FTHMToken.balanceOf(staker_1); await blockchain.increaseTime(20); @@ -385,8 +385,8 @@ describe("Staking Test and Upgrade Test", () => { const sumToDepositForAll = web3.utils.toWei('0.11', 'ether'); - await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_2}) - await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_3}) + await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_2}) + await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_3}) await blockchain.mineBlock(await _getTimeStamp() + 20); console.log(".........Creating a Lock Position for staker 2 and Staker 3......."); @@ -519,7 +519,7 @@ describe("Staking Test and Upgrade Test", () => { }); it("Should not early unlock", async() => { - await FTHMToken.approve(stakingService.address, sumToApprove, {from: SYSTEM_ACC}) + await FTHMToken.approve(vaultService.address, sumToApprove, {from: SYSTEM_ACC}) let lockingPeriod = 365 * 24 * 60 * 60; await stakingService.createLockWithoutEarlyWithdraw(sumToDeposit,lockingPeriod, staker_5,{from: SYSTEM_ACC}); await blockchain.mineBlock(await _getTimeStamp() + 20); @@ -531,6 +531,7 @@ describe("Staking Test and Upgrade Test", () => { errorMessage ); }) + }); describe('Creating Streams and Rewards Calculations', async() => { diff --git a/scripts/tests/dao/full-flow-demo.test.js b/scripts/tests/dao/full-flow-demo.test.js index f4498fd..81d335e 100644 --- a/scripts/tests/dao/full-flow-demo.test.js +++ b/scripts/tests/dao/full-flow-demo.test.js @@ -410,7 +410,7 @@ describe("DAO Demo", () => { let expectedTotalAmountOfVFTHM = new web3.utils.BN(0) it('Should create a lock possition with lockId = 1 for staker_1', async() => { - await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_1}) + await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_1}) await blockchain.increaseTime(20); let lockingPeriod = 365 * 24 * 60 * 60; @@ -447,7 +447,7 @@ describe("DAO Demo", () => { }) it('Should create 2 lock positions with lockId = 1 and lockId = 2 for staker_2', async() => { - await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_2}); + await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_2}); await blockchain.increaseTime(20); let lockingPeriod = 365 * 24 * 60 * 60; @@ -954,7 +954,7 @@ describe("DAO Demo", () => { result = await multiSigWallet.submitTransaction( FTHMToken.address, EMPTY_BYTES, - _encodeStakeApproveFunction(approveAmount, stakingService.address), + _encodeStakeApproveFunction(approveAmount, vaultService.address), 0, {"from": accounts[0]} ); diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 5141248..0c9bf35 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -202,7 +202,7 @@ describe('Proposal flow', () => { const _stakeMainGetVe = async (_account) => { await _transferFromMultiSigTreasury(_account); - await FTHMToken.approve(stakingService.address, T_TO_STAKE, {from: _account}); + await FTHMToken.approve(vaultService.address, T_TO_STAKE, {from: _account}); await blockchain.increaseTime(20); let unlockTime = lockingPeriod; @@ -428,7 +428,7 @@ describe('Proposal flow', () => { const _stakeMainGetVe = async (_account) => { await _transferFromMultiSigTreasury(_account); - await FTHMToken.approve(stakingService.address, T_TO_STAKE, {from: _account}); + await FTHMToken.approve(vaultService.address, T_TO_STAKE, {from: _account}); await blockchain.increaseTime(20); let unlockTime = lockingPeriod; diff --git a/scripts/tests/dao/governance/token-creation-though-gov.test.js b/scripts/tests/dao/governance/token-creation-though-gov.test.js index 85f21f7..28af5b2 100644 --- a/scripts/tests/dao/governance/token-creation-though-gov.test.js +++ b/scripts/tests/dao/governance/token-creation-though-gov.test.js @@ -167,7 +167,7 @@ describe('Token Creation Through Governance', () => { const _stakeMainGetVe = async (_account) => { await _transferFromMultiSigTreasury(_account); - await FTHMToken.approve(stakingService.address, T_TO_STAKE, {from: _account}); + await FTHMToken.approve(vaultService.address, T_TO_STAKE, {from: _account}); await blockchain.increaseTime(20); let unlockTime = lockingPeriod; diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index 20650cc..86808be 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -347,7 +347,7 @@ describe("Staking Test", () => { expectedTotalAmountOfVFTHM = new web3.utils.BN(0) it('Should create a lock possition with lockId = 1 for staker_1', async() => { // So that staker 1 can actually stake the token: - await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_1}) + await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_1}) const beforeFTHMBalance = await FTHMToken.balanceOf(staker_1); await blockchain.increaseTime(20); @@ -416,9 +416,9 @@ describe("Staking Test", () => { const sumToDepositForAll = web3.utils.toWei('100', 'ether'); - await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_2}) - await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_3}) - await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_4}) + await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_2}) + await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_3}) + await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_4}) await blockchain.mineBlock(await _getTimeStamp() + 20); @@ -1129,7 +1129,7 @@ describe("Staking Test", () => { const sumToApprove = web3.utils.toWei('20000','ether'); - await FTHMToken.approve(stakingService.address, sumToApprove, {from: accounts[9]}) + await FTHMToken.approve(vaultService.address, sumToApprove, {from: accounts[9]}) const lockingPeriod = 365 * 24 * 60 * 60 const unlockTime = lockingPeriod; @@ -1255,6 +1255,32 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + 100); }) + it('Should should make lock position on behalf', async() => { + const unlockTime = 0; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime, staker_4,{from: staker_3, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should should make lock position on behalf', async() => { + const unlockTime = 0; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime, staker_4,{from: staker_3, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should revert after max lock positions on behalf',async() => { + const unlockTime = 0; + await blockchain.mineBlock(await _getTimeStamp() + 100); + const errorMessage = "max lock on behalf"; + await shouldRevert( + stakingService.createLock(sumToDeposit,unlockTime, staker_4,{from: staker_3, gas: maxGasForTxn}), + errTypes.revert, + errorMessage + ) + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + it('Should not be initalizable twice - Vault', async() => { const errorMessage = "Initializable: contract is already initialized"; From 6e72d2a38252cb3b72bd6279a30cba0193927fb9 Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 2 Jan 2023 17:20:23 +0545 Subject: [PATCH 17/77] brushing up final audit fixes --- .../prod/1_deploy_init_staking_proxy.js | 63 +++++++--- .../{test => prod}/3_init_vToken.js | 0 ..._owner.js => 4_setup_proxy_admin_owner.js} | 0 scripts/migrations/prod/5_init_main_stream.js | 111 ++++++++++++++++++ ...il_stakes.js => 6_setup_council_stakes.js} | 3 +- .../migrations/prod/6_setup_vault_tokens.js | 46 -------- ...helpers.js => 8_staking_getter_helpers.js} | 0 .../test/2_deploy_init_staking_proxy.js | 18 --- .../4_init_vToken.js} | 0 ..._vault_tokens.js => 6_init_main_stream.js} | 0 ...helpers.js => 8_staking_getter_helpers.js} | 0 11 files changed, 159 insertions(+), 82 deletions(-) rename scripts/migrations/{test => prod}/3_init_vToken.js (100%) rename scripts/migrations/prod/{3_setup_proxy_admin_owner.js => 4_setup_proxy_admin_owner.js} (100%) create mode 100644 scripts/migrations/prod/5_init_main_stream.js rename scripts/migrations/prod/{5_setup_council_stakes.js => 6_setup_council_stakes.js} (94%) delete mode 100644 scripts/migrations/prod/6_setup_vault_tokens.js rename scripts/migrations/prod/{4_staking_getter_helpers.js => 8_staking_getter_helpers.js} (100%) rename scripts/migrations/{prod/2_init_vToken.js => test/4_init_vToken.js} (100%) rename scripts/migrations/test/{6_setup_vault_tokens.js => 6_init_main_stream.js} (100%) rename scripts/migrations/test/{4_staking_getter_helpers.js => 8_staking_getter_helpers.js} (100%) diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index 5a04c47..ec541c9 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -42,6 +42,46 @@ const _getTimeStamp = async () => { const timestamp = await blockchain.getLatestBlockTimestamp(); return timestamp; } +const _encodeApproveFunction = (_account, _amount) => { + let toRet = web3.eth.abi.encodeFunctionCall({ + name: 'approve', + type: 'function', + inputs: [{ + type: 'address', + name: 'spender' + },{ + type: 'uint256', + name: 'amount' + }] + }, [_account, _amount]); + + return toRet; +} + +const _encodeInitMainStreamFunction = (_owner, _scheduleTimes, _scheduleRewards, tau) => { + let toInitializeMainStream = web3.eth.abi.encodeFunctionCall({ + name: 'initializeMainStream', + type: 'function', + inputs: [{ + type: 'address', + name: '_owner' + }, + { + type: 'uint256[]', + name: 'scheduleTimes' + }, + { + type: 'uint256[]', + name: 'scheduleRewards' + }, + { + type: 'uint256', + name: 'tau' + }] + }, [MultiSigWallet.address, _scheduleTimes, _scheduleRewards, tau]); + + return toInitializeMainStream +} const vMainTokenCoefficient = 500; @@ -53,7 +93,7 @@ const maxWeightPenalty = 3000; const minWeightPenalty = 100; const weightMultiplier = 10; const maxNumberOfLocks = 10; - +const maxOnBehalfLockPositions = 5; const tau = 2; const lockingVoteWeight = 365 * 24 * 60 * 60; @@ -125,18 +165,6 @@ module.exports = async function(deployer) { {"type": "uint32", "name":"penaltyWeightMultiplier"} ] }, - { - type: 'uint256[]', - name: 'scheduleTimes' - }, - { - type: 'uint256[]', - name: 'scheduleRewards' - }, - { - type: 'uint256', - name: 'tau' - }, { type: 'tuple', name: 'VoteCoefficient', @@ -152,15 +180,16 @@ module.exports = async function(deployer) { { type: 'address', name: '_rewardsContract' + }, + { + type: 'uint256', + name: '_maxOnBehalfLockPositions' }] }, [MultiSigWallet.address, vaultService.address, MainToken.address, VMainToken.address, - weightObject, scheduleTimes, scheduleRewards, tau, - voteObject, maxNumberOfLocks, RewardsCalculator.address]); + weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address,maxOnBehalfLockPositions]); await deployer.deploy(StakingProxyAdmin, {gas:8000000}); await deployer.deploy(StakingProxy, StakingPackage.address, StakingProxyAdmin.address, toInitialize, {gas:8000000}); - - await vaultService.initRewardsOperator(StakingProxy.address) } catch(error) { console.log(error) } diff --git a/scripts/migrations/test/3_init_vToken.js b/scripts/migrations/prod/3_init_vToken.js similarity index 100% rename from scripts/migrations/test/3_init_vToken.js rename to scripts/migrations/prod/3_init_vToken.js diff --git a/scripts/migrations/prod/3_setup_proxy_admin_owner.js b/scripts/migrations/prod/4_setup_proxy_admin_owner.js similarity index 100% rename from scripts/migrations/prod/3_setup_proxy_admin_owner.js rename to scripts/migrations/prod/4_setup_proxy_admin_owner.js diff --git a/scripts/migrations/prod/5_init_main_stream.js b/scripts/migrations/prod/5_init_main_stream.js new file mode 100644 index 0000000..61cca40 --- /dev/null +++ b/scripts/migrations/prod/5_init_main_stream.js @@ -0,0 +1,111 @@ +const eventsHelper = require("../../tests/helpers/eventsHelper"); + +const IVault = artifacts.require('./dao/staking/vault/interfaces/IVault.sol'); +const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); +const IERC20 = artifacts.require("./dao/tokens/ERC20/IERC20.sol"); +const blockchain = require("../../tests/helpers/blockchain"); + +const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); +const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); +const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; +const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; + +const T_TO_TRANSFER = web3.utils.toWei('20000', 'ether'); +const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') +const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') + + +const _getTimeStamp = async () => { + const timestamp = await blockchain.getLatestBlockTimestamp(); + return timestamp; +} + +const _encodeApproveFunction = (_account, _amount) => { + let toRet = web3.eth.abi.encodeFunctionCall({ + name: 'approve', + type: 'function', + inputs: [{ + type: 'address', + name: 'spender' + },{ + type: 'uint256', + name: 'amount' + }] + }, [_account, _amount]); + + return toRet; +} + +const _encodeInitMainStreamFunction = (_owner, _scheduleTimes, _scheduleRewards, tau) => { + let toInitializeMainStream = web3.eth.abi.encodeFunctionCall({ + name: 'initializeMainStream', + type: 'function', + inputs: [{ + type: 'address', + name: '_owner' + }, + { + type: 'uint256[]', + name: 'scheduleTimes' + }, + { + type: 'uint256[]', + name: 'scheduleRewards' + }, + { + type: 'uint256', + name: 'tau' + }] + }, [MultiSigWallet.address, _scheduleTimes, _scheduleRewards, tau]); + + return toInitializeMainStream +} + +const tau = 2; + +module.exports = async function(deployer) { + const startTime = await _getTimeStamp() + 3 * 24 * 60 * 60; + const oneYear = 31556926; + const scheduleTimes = [ + startTime, + startTime + oneYear, + startTime + 2 * oneYear, + startTime + 3 * oneYear, + startTime + 4 * oneYear, + ]; + + const scheduleRewards = [ + web3.utils.toWei('20000', 'ether'), + web3.utils.toWei('10000', 'ether'), + web3.utils.toWei('5000', 'ether'), + web3.utils.toWei('2500', 'ether'), + web3.utils.toWei("0", 'ether') + ]; + + + const multiSigWallet = await IMultiSigWallet.at(MultiSigWallet.address) + + let resultApprove = await multiSigWallet.submitTransaction( + MainToken.address, + EMPTY_BYTES, + _encodeApproveFunction(VaultProxy.address,scheduleRewards[0]), + 0, + {gas: 8000000} + ) + + let txIndexApprove = eventsHelper.getIndexedEventArgs(resultApprove, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(txIndexApprove, {gas: 8000000}); + await multiSigWallet.executeTransaction(txIndexApprove, {gas: 8000000}); + + let resultInit = await multiSigWallet.submitTransaction( + StakingProxy.address, + EMPTY_BYTES, + _encodeInitMainStreamFunction(MultiSigWallet.address,scheduleTimes, scheduleRewards,tau), + 0, + {gas: 8000000} + ); + + let txIndexInit = eventsHelper.getIndexedEventArgs(resultInit, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(txIndexInit, {gas: 8000000}); + await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); +} diff --git a/scripts/migrations/prod/5_setup_council_stakes.js b/scripts/migrations/prod/6_setup_council_stakes.js similarity index 94% rename from scripts/migrations/prod/5_setup_council_stakes.js rename to scripts/migrations/prod/6_setup_council_stakes.js index c23da86..685a014 100644 --- a/scripts/migrations/prod/5_setup_council_stakes.js +++ b/scripts/migrations/prod/6_setup_council_stakes.js @@ -19,6 +19,7 @@ const T_TO_STAKE = web3.utils.toWei('50000', 'ether'); const COUNCIL_1 = "0xc0Ee98ac1a44B56fbe2669A3B3C006DEB6fDd0f9"; const COUNCIL_2 = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') +const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') const _encodeTransferFunction = (_account, _amount) => { @@ -54,7 +55,7 @@ module.exports = async function(deployer) { await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); - await mainToken.approve(stakingService.address, T_TO_TRANSFER, {gas: 8000000}); + await mainToken.approve(VaultProxy.address, T_TO_TRANSFER, {gas: 8000000}); await stakingService.createLockWithoutEarlyWithdraw(T_TO_STAKE, LOCK_PERIOD, accounts[0], {gas: 600000}); await stakingService.createLockWithoutEarlyWithdraw(T_TO_STAKE, LOCK_PERIOD, COUNCIL_1, {gas: 600000}); diff --git a/scripts/migrations/prod/6_setup_vault_tokens.js b/scripts/migrations/prod/6_setup_vault_tokens.js deleted file mode 100644 index 5561d68..0000000 --- a/scripts/migrations/prod/6_setup_vault_tokens.js +++ /dev/null @@ -1,46 +0,0 @@ -const eventsHelper = require("../../tests/helpers/eventsHelper"); - -const IVault = artifacts.require('./dao/staking/vault/interfaces/IVault.sol'); -const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); -const IERC20 = artifacts.require("./dao/tokens/ERC20/IERC20.sol"); - -const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); -const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); -const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; -const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; - -const T_TO_TRANSFER = web3.utils.toWei('20000', 'ether'); -const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') - - -const _encodeTransferFunction = (_account, _amount) => { - let toRet = web3.eth.abi.encodeFunctionCall({ - name: 'transfer', - type: 'function', - inputs: [{ - type: 'address', - name: 'to' - },{ - type: 'uint256', - name: 'amount' - }] - }, [_account, _amount]); - - return toRet; -} - -module.exports = async function(deployer) { - const vaultService = await IVault.at(VaultProxy.address) - const multiSigWallet = await IMultiSigWallet.at(MultiSigWallet.address) - let result = await multiSigWallet.submitTransaction( - MainToken.address, - EMPTY_BYTES, - _encodeTransferFunction(vaultService.address, T_TO_TRANSFER), - 0, - {gas: 8000000} - ); - - let txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; - await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); - await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); -} diff --git a/scripts/migrations/prod/4_staking_getter_helpers.js b/scripts/migrations/prod/8_staking_getter_helpers.js similarity index 100% rename from scripts/migrations/prod/4_staking_getter_helpers.js rename to scripts/migrations/prod/8_staking_getter_helpers.js diff --git a/scripts/migrations/test/2_deploy_init_staking_proxy.js b/scripts/migrations/test/2_deploy_init_staking_proxy.js index 97c5caa..e9873c3 100644 --- a/scripts/migrations/test/2_deploy_init_staking_proxy.js +++ b/scripts/migrations/test/2_deploy_init_staking_proxy.js @@ -71,24 +71,6 @@ module.exports = async function(deployer) { ); - const startTime = await _getTimeStamp() + 3 * 24 * 60 * 60; - - const scheduleTimes = [ - startTime, - startTime + oneYear, - startTime + 2 * oneYear, - startTime + 3 * oneYear, - startTime + 4 * oneYear, - ]; - - const scheduleRewards = [ - web3.utils.toWei('20000', 'ether'), - web3.utils.toWei('10000', 'ether'), - web3.utils.toWei('5000', 'ether'), - web3.utils.toWei('2500', 'ether'), - web3.utils.toWei("0", 'ether') - ]; - const voteObject = _createVoteWeights( vMainTokenCoefficient, lockingVoteWeight diff --git a/scripts/migrations/prod/2_init_vToken.js b/scripts/migrations/test/4_init_vToken.js similarity index 100% rename from scripts/migrations/prod/2_init_vToken.js rename to scripts/migrations/test/4_init_vToken.js diff --git a/scripts/migrations/test/6_setup_vault_tokens.js b/scripts/migrations/test/6_init_main_stream.js similarity index 100% rename from scripts/migrations/test/6_setup_vault_tokens.js rename to scripts/migrations/test/6_init_main_stream.js diff --git a/scripts/migrations/test/4_staking_getter_helpers.js b/scripts/migrations/test/8_staking_getter_helpers.js similarity index 100% rename from scripts/migrations/test/4_staking_getter_helpers.js rename to scripts/migrations/test/8_staking_getter_helpers.js From b84425f7b80b2c97f8fc362fcf5c80f9f6918b39 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 5 Jan 2023 12:13:46 +0545 Subject: [PATCH 18/77] audit fixes --- audit-report/Fathom_DAO.md | 4 +- contracts/dao/governance/Governor.sol | 52 ++++++++--- .../dao/governance/MainTokenGovernor.sol | 22 +++-- .../dao/governance/TimelockController.sol | 2 +- contracts/dao/staking/StakingStorage.sol | 4 +- contracts/dao/staking/StakingStructs.sol | 1 - .../staking/interfaces/IStakingHandler.sol | 9 +- .../dao/staking/packages/StakingGetters.sol | 2 +- .../dao/staking/packages/StakingHandler.sol | 48 +++++----- .../dao/staking/packages/StakingInternals.sol | 7 +- .../prod/1_deploy_init_staking_proxy.js | 73 +--------------- .../migrations/prod/6_setup_council_stakes.js | 12 ++- .../test/2_deploy_init_staking_proxy.js | 8 +- scripts/tests/dao/demo/staking.demo.test.js | 21 +---- scripts/tests/dao/full-flow-demo.test.js | 52 +++++------ .../dao/governance/proposal-flow.test.js | 12 ++- .../token-creation-though-gov.test.js | 2 +- scripts/tests/dao/staking/staking.test.js | 87 +++++++------------ 18 files changed, 166 insertions(+), 252 deletions(-) diff --git a/audit-report/Fathom_DAO.md b/audit-report/Fathom_DAO.md index 4a1333b..1c464d8 100644 --- a/audit-report/Fathom_DAO.md +++ b/audit-report/Fathom_DAO.md @@ -189,7 +189,7 @@ In the structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-s ##### Recommendation We recommend adding an individual parameter, which is responsible for the maximum time until the transaction can be executed, e.g. `expired` and check it before running transactions. -#### [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[DONE] +#### [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[DONE, MAXJI] ##### Description In the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, Governance can take away the `TIMELOCK_ADMIN_ROLE` rights from the address `admin`. In the case of an attack on `Governance` and `Council` this would make it impossible to revoke the role from the captured contracts. ##### Recommendation @@ -231,7 +231,7 @@ In the `GovernorVotesQuorumFraction` contract in the [`_updateQuorumNumerator`]( We recommend adding a constant with the minimum allowable value of `_quorumNumerator` and perform a corresponding check in the `_updateQuorumNumerator` function. -#### [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE,check it again] +#### [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE,Check Again, TODO] ##### Description In the [VMainToken](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) contract, for mint tokens, calling account, in addition to having `MINTER_ROLE` rights, must also be in the `isWhiteListed` list, since the mint function calls `_mint,` which contains [`_beforeTokenTransfer`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65) call. When `_beforeTokenTransfer` is called, it checks that the `msg.sender` address is in the `isWhiteListed` list. diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 8ab32cc..f54fd43 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -14,8 +14,9 @@ import "../../common/Context.sol"; import "../../common/Strings.sol"; import "./GovernorStructs.sol"; import "./interfaces/IGovernor.sol"; +import "../../common/security/Pausable.sol"; -abstract contract Governor is Context, ERC165, EIP712, IGovernor { +abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; using SafeCast for uint256; using Strings for *; @@ -26,18 +27,21 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { event ExecuteProposal(address indexed signer, uint indexed proposalId); event MultiSigUpdated(address newMultiSig, address oldMultiSig); event MaxTargetUpdated(uint256 newMaxTargets, uint256 oldMaxTargets); + event ProposalTimeDelayUpdated(uint256 newProposalTimeDelay, uint256 oldProposalTimeDelay); bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); uint256 public maxTargets; + uint256 public proposalTimeDelay; string private _name; uint256[] private proposalIds; - + address private multiSig; mapping(uint256 => ProposalCore) internal _proposals; mapping(uint256 => string) internal _descriptions; mapping(uint => bool) public isConfirmed; + mapping(address => uint) public nextAcceptableProposalTimestamp; DoubleEndedQueue.Bytes32Deque private _governanceCall; @@ -66,12 +70,19 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { _; } - constructor(string memory name_, address _multiSig, uint256 _maxTargets) EIP712(name_, version()) { - require(_multiSig != address(0),"multiSig address cant be zero address"); - require(_maxTargets != 0,"maxTarget cant be zero"); + constructor( + string memory name_, + address multiSig_, + uint256 maxTargets_, + uint256 proposalTimeDelay_) EIP712(name_, version()) + { + require(multiSig_ != address(0),"multiSig address cant be zero address"); + require(maxTargets_ != 0,"maxTarget cant be zero"); + require(proposalTimeDelay_ != 0,"proposalTimeDelay cant be zero"); _name = name_; - multiSig = _multiSig; - maxTargets = _maxTargets; + multiSig = multiSig_; + maxTargets = maxTargets_; + proposalTimeDelay = proposalTimeDelay_; } receive() external payable virtual { @@ -83,7 +94,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash - ) public payable virtual override returns (uint256) { + ) public whenNotPaused payable virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); requireConfirmed(proposalId); @@ -158,15 +169,21 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { uint256[] memory values, bytes[] memory calldatas, string memory description - ) public virtual override returns (uint256) { + ) public whenNotPaused virtual override returns (uint256) { + require(getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold"); + + require(block.timestamp > nextAcceptableProposalTimestamp[msg.sender], + "Governor: Can only submit one proposal for a certain interval"); + + nextAcceptableProposalTimestamp[msg.sender] = block.timestamp + proposalTimeDelay; uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); require(targets.length == values.length, "Governor: invalid proposal length"); require(targets.length == calldatas.length, "Governor: invalid proposal length"); require(targets.length > 0, "Governor: empty proposal"); - require(targets.length <= maxTargets,"Governor: invalid proposal length"); + require(targets.length <= maxTargets,"Governor: max target length"); ProposalCore storage proposal = _proposals[proposalId]; require(proposal.voteStart.isUnset(), "Governor: proposal already exists"); @@ -211,6 +228,21 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { emit MaxTargetUpdated(newMaxTargets, maxTargets); maxTargets = newMaxTargets; } + + function updateProposalTimeDelay(uint256 newProposalTimeDelay) public onlyMultiSig { + require(newProposalTimeDelay != 0,"updateProposalTimeDelay: newProposalTimeDelay cant be zero"); + emit MaxTargetUpdated(newProposalTimeDelay, proposalTimeDelay); + proposalTimeDelay = newProposalTimeDelay; + } + + function emergencyStop() public onlyMultiSig{ + _pause(); + } + + function unpause() public onlyMultiSig{ + _unpause(); + } + function getProposals(uint _numIndexes) public view override returns (string[] memory, string[] memory, string[] memory) { uint len = proposalIds.length; diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index c4ad7d9..f182f19 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -22,7 +22,7 @@ contract MainTokenGovernor is { using SafeERC20 for IERC20; mapping(address => bool) public isSupportedToken; - + uint256 public constant EIGHT_HOURS = 28800; constructor( IVotes _token, TimelockController _timelock, @@ -31,7 +31,7 @@ contract MainTokenGovernor is uint256 _votingPeriod, uint256 _initialProposalThreshold ) - Governor("MainTokenGovernor", _multiSig,20) + Governor("MainTokenGovernor", _multiSig,20,EIGHT_HOURS) GovernorSettings(_initialVotingDelay, _votingPeriod, _initialProposalThreshold) GovernorVotes(_token) GovernorVotesQuorumFraction(4) @@ -90,11 +90,17 @@ contract MainTokenGovernor is isSupportedToken[_token] = false; } - function withdrawToken(address _token, address _withdrawTo) public onlyMultiSig { - require(isSupportedToken[_token],"Token is not supported"); - uint256 balance = IERC20(_token).balanceOf(address(this)); - IERC20(_token).safeTransfer(_withdrawTo, balance); - } + /** + * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor + * is some contract other than the governor itself, like when using a timelock, this function can be invoked + * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. + * Note that if the executor is simply the governor itself, use of `relay` is redundant. + */ + function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance { + require(isSupportedToken[target],"relay: token not supported"); + (bool success, bytes memory returndata) = target.call{value: value}(data); + Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); + } function _execute( uint256 proposalId, @@ -119,6 +125,4 @@ contract MainTokenGovernor is function _executor() internal view override(Governor, GovernorTimelockControl) returns (address) { return super._executor(); } - - } diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index 16f5ad3..4c67b15 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -109,7 +109,7 @@ contract TimelockController is AccessControl, Initializable, ITimelockController emit Cancelled(id); } - + //TODO function execute( address target, uint256 value, diff --git a/contracts/dao/staking/StakingStorage.sol b/contracts/dao/staking/StakingStorage.sol index f4ba7c2..2dbc725 100644 --- a/contracts/dao/staking/StakingStorage.sol +++ b/contracts/dao/staking/StakingStorage.sol @@ -42,6 +42,7 @@ contract StakingStorage { address public voteToken; address public vault; address public rewardsCalculator; + bool public councilsInitialized; ///Weighting coefficient for shares and penalties Weight internal weight; @@ -49,10 +50,7 @@ contract StakingStorage { mapping(address => User) public users; Stream[] internal streams; - - uint256 internal maxOnBehalfLockPositions; ///Mapping (user => LockedBalance) to keep locking information for each user mapping(address => LockedBalance[]) internal locks; mapping(uint256 => uint256) public streamTotalUserPendings; - mapping(address => uint256) internal nOnBehalfLocks; } diff --git a/contracts/dao/staking/StakingStructs.sol b/contracts/dao/staking/StakingStructs.sol index 1ff87e2..feb3e09 100644 --- a/contracts/dao/staking/StakingStructs.sol +++ b/contracts/dao/staking/StakingStructs.sol @@ -49,7 +49,6 @@ struct LockedBalance { uint128 amountOfVoteToken; uint128 positionStreamShares; uint64 end; - bool onBehalf; address owner; } struct Stream { diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index 8b455d4..bbed999 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -15,8 +15,7 @@ interface IStakingHandler { Weight calldata _weight, VoteCoefficient memory voteCoef, uint256 _maxLocks, - address _rewardsContract, - uint256 _maxOnBehalfLockPositions + address _rewardsContract ) external; function initializeMainStream( @@ -41,9 +40,8 @@ interface IStakingHandler { function removeStream(uint256 streamId, address streamFundReceiver) external; - function createLock(uint256 amount, uint256 lockPeriod, address account) external; + function createLock(uint256 amount, uint256 lockPeriod) external; - function createLockWithoutEarlyWithdraw(uint256 amount, uint256 lockPeriod, address account) external; function unlockPartially(uint256 lockId, uint256 amount) external; @@ -51,8 +49,6 @@ interface IStakingHandler { function earlyUnlock(uint256 lockId) external; - function claimRewards(uint256 streamId, uint256 lockId) external; - function claimAllStreamRewardsForLock(uint256 lockId) external; function claimAllLockRewardsForStream(uint256 streamId) external; @@ -65,4 +61,5 @@ interface IStakingHandler { function updateVault(address _vault) external; function emergencyUnlockAndWithdraw() external; + function createLocksForCouncils(uint256[] memory amounts, uint256[] memory lockPeriods, address[] memory accounts) external; } diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index af9708c..3b10abf 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -18,7 +18,7 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { } function getStreamClaimableAmountPerLock(uint256 streamId, address account, uint256 lockId) external view override returns (uint256) { - require(streams[streamId].status == StreamStatus.ACTIVE, "stream not active"); + require(streams[streamId].status == StreamStatus.ACTIVE, "stream inactive"); require(lockId <= locks[account].length, "bad index"); uint256 latestRps = _getLatestRewardsPerShare(streamId); User storage userAccount = users[account]; diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 1bed169..6771680 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -35,8 +35,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A Weight calldata _weight, VoteCoefficient memory voteCoef, uint256 _maxLocks, - address _rewardsContract, - uint256 _maxOnBehalfLockPositions + address _rewardsContract ) external override initializer{ rewardsCalculator = _rewardsContract; _initializeStaking(_mainToken, _voteToken, _weight, _vault, _maxLocks, voteCoef.voteShareCoef, voteCoef.voteLockCoef); @@ -45,7 +44,6 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _grantRole(STREAM_MANAGER_ROLE, _admin); _grantRole(TREASURY_ROLE, _admin); maxLockPeriod = ONE_YEAR; - maxOnBehalfLockPositions = _maxOnBehalfLockPositions; } function initializeMainStream( @@ -149,7 +147,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A if (rewardTokenAmount < stream.maxDepositAmount) { _updateStreamsRewardsSchedules(streamId, rewardTokenAmount); } - require(stream.schedule.reward[0] == stream.rewardDepositAmount, "bad start point"); + require(stream.schedule.reward[0] == stream.rewardDepositAmount, "bad start"); emit StreamCreated(streamId, stream.owner, stream.rewardToken, rewardTokenAmount); IVault(vault).deposit(msg.sender, stream.rewardToken, rewardTokenAmount); @@ -165,7 +163,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function removeStream(uint256 streamId, address streamFundReceiver) public override onlyRole(STREAM_MANAGER_ROLE) { require(streamId != 0, "Stream 0"); - require(streamTotalUserPendings[streamId] == 0, "stream not withdrawn"); + require(streamTotalUserPendings[streamId] == 0, "nt withdrawn"); Stream storage stream = streams[streamId]; require(stream.status == StreamStatus.ACTIVE, "No Stream"); stream.status = StreamStatus.INACTIVE; @@ -181,16 +179,28 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A emit StreamRemoved(streamId, stream.owner, stream.rewardToken); } - function createLockWithoutEarlyWithdraw(uint256 amount, uint256 lockPeriod, address account) public override pausable(1) { - prohibitedEarlyWithdraw[account][locks[account].length + 1] = true; - _createLock(amount, lockPeriod, account); + function createLocksForCouncils( + uint256[] memory amounts, + uint256[] memory lockPeriods, + address[] memory accounts) public override + { + require(!councilsInitialized,"already created"); + require( + amounts.length == lockPeriods.length + && amounts.length == lockPeriods.length,"bad len"); + + councilsInitialized = true; + for(uint i = 0; i < amounts.length; i++){ + prohibitedEarlyWithdraw[accounts[i]][locks[accounts[i]].length + 1] = true; + _createLock(amounts[i], lockPeriods[i], accounts[i]); + } } - function createLock(uint256 amount, uint256 lockPeriod, address account) public override pausable(1) { - _createLock(amount, lockPeriod, account); + function createLock(uint256 amount, uint256 lockPeriod) public override pausable(1) { + _createLock(amount, lockPeriod, msg.sender); } - function unlock(uint256 lockId) public override { + function unlock(uint256 lockId) public override pausable(1) { _verifyUnlock(lockId); LockedBalance storage lock = locks[msg.sender][lockId - 1]; require(lock.end <= block.timestamp, "lock not open"); @@ -220,13 +230,6 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } - function claimRewards(uint256 streamId, uint256 lockId) public override pausable(1) { - require(lockId <= locks[msg.sender].length, "bad lockid"); - require(lockId != 0, "lockId zero"); - _updateStreamRPS(); - _moveRewardsToPending(msg.sender, streamId, lockId); - } - function claimAllStreamRewardsForLock(uint256 lockId) public override pausable(1) { require(lockId <= locks[msg.sender].length, "bad lockid"); require(lockId != 0, "lockId zero"); @@ -244,7 +247,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A User storage userAccount = users[msg.sender]; require(userAccount.pendings[streamId] != 0, "no pendings"); require(block.timestamp > userAccount.releaseTime[streamId], "not released"); - require(streams[streamId].status == StreamStatus.ACTIVE,"stream nt active"); + require(streams[streamId].status == StreamStatus.ACTIVE,"stream inactive"); _withdraw(streamId); } @@ -279,7 +282,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function updateVault(address _vault) public override onlyRole(DEFAULT_ADMIN_ROLE) { // enforce pausing this contract before updating the address. // This mitigates the risk of future invalid reward claims - require(paused != 0, "required pause"); + require(paused != 0, "require pause"); require(_vault != address(0), "zero addr"); require(IVault(vault).migrated(),"nt migrated"); vault = _vault; @@ -299,14 +302,11 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A IVault(vault).deposit(msg.sender, mainToken, amount); } - function _verifyUnlock(uint256 lockId) internal { + function _verifyUnlock(uint256 lockId) internal view{ require(lockId > 0, "zero lockid"); require(lockId <= locks[msg.sender].length, "bad lockid"); LockedBalance storage lock = locks[msg.sender][lockId - 1]; require(lock.amountOfToken > 0, "no amount"); require(lock.owner == msg.sender, "bad owner"); - if(lock.onBehalf == true && nOnBehalfLocks[msg.sender] >0){ - nOnBehalfLocks[msg.sender] -= 1; - } } } diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 6c6872f..09caa27 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -48,13 +48,8 @@ contract StakingInternals is StakingStorage, RewardsInternals { userAccount.voteTokenBalance += BoringMath.to128(nVoteToken); totalAmountOfVoteToken += nVoteToken; } - if(account != msg.sender){ - require(nOnBehalfLocks[account] < maxOnBehalfLockPositions,"max lock on behalf"); - nOnBehalfLocks[account]+=1; - } LockedBalance memory _newLock = LockedBalance({ amountOfToken: BoringMath.to128(amount), - onBehalf: true ? msg.sender != account : false, amountOfVoteToken: BoringMath.to128(nVoteToken), positionStreamShares: 0, end: BoringMath.to64(lockPeriod + block.timestamp), @@ -82,7 +77,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { function _unlock(uint256 stakeValue, uint256 amount, uint256 lockId, address account) internal { User storage userAccount = users[account]; LockedBalance storage updateLock = locks[account][lockId - 1]; - require(totalAmountOfStakedToken != 0, "Zero total tokens"); + require(totalAmountOfStakedToken != 0, "Zero tokens"); require(updateLock.amountOfToken != 0, "No token"); uint256 nVoteToken = updateLock.amountOfVoteToken; /// if you unstake, early or partial or complete, diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index ec541c9..9b9d697 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -38,52 +38,7 @@ const _createVoteWeights = ( } } -const _getTimeStamp = async () => { - const timestamp = await blockchain.getLatestBlockTimestamp(); - return timestamp; -} -const _encodeApproveFunction = (_account, _amount) => { - let toRet = web3.eth.abi.encodeFunctionCall({ - name: 'approve', - type: 'function', - inputs: [{ - type: 'address', - name: 'spender' - },{ - type: 'uint256', - name: 'amount' - }] - }, [_account, _amount]); - - return toRet; -} - -const _encodeInitMainStreamFunction = (_owner, _scheduleTimes, _scheduleRewards, tau) => { - let toInitializeMainStream = web3.eth.abi.encodeFunctionCall({ - name: 'initializeMainStream', - type: 'function', - inputs: [{ - type: 'address', - name: '_owner' - }, - { - type: 'uint256[]', - name: 'scheduleTimes' - }, - { - type: 'uint256[]', - name: 'scheduleRewards' - }, - { - type: 'uint256', - name: 'tau' - }] - }, [MultiSigWallet.address, _scheduleTimes, _scheduleRewards, tau]); - - return toInitializeMainStream -} - - const vMainTokenCoefficient = 500; +const vMainTokenCoefficient = 500; const oneYear = 31556926; @@ -93,8 +48,6 @@ const maxWeightPenalty = 3000; const minWeightPenalty = 100; const weightMultiplier = 10; const maxNumberOfLocks = 10; -const maxOnBehalfLockPositions = 5; -const tau = 2; const lockingVoteWeight = 365 * 24 * 60 * 60; @@ -111,24 +64,6 @@ module.exports = async function(deployer) { ); - const startTime = await _getTimeStamp() + 3 * 24 * 60 * 60; - - const scheduleTimes = [ - startTime, - startTime + oneYear, - startTime + 2 * oneYear, - startTime + 3 * oneYear, - startTime + 4 * oneYear, - ]; - - const scheduleRewards = [ - web3.utils.toWei('20000', 'ether'), - web3.utils.toWei('10000', 'ether'), - web3.utils.toWei('5000', 'ether'), - web3.utils.toWei('2500', 'ether'), - web3.utils.toWei("0", 'ether') - ]; - const voteObject = _createVoteWeights( vMainTokenCoefficient, lockingVoteWeight @@ -180,13 +115,9 @@ module.exports = async function(deployer) { { type: 'address', name: '_rewardsContract' - }, - { - type: 'uint256', - name: '_maxOnBehalfLockPositions' }] }, [MultiSigWallet.address, vaultService.address, MainToken.address, VMainToken.address, - weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address,maxOnBehalfLockPositions]); + weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address]); await deployer.deploy(StakingProxyAdmin, {gas:8000000}); await deployer.deploy(StakingProxy, StakingPackage.address, StakingProxyAdmin.address, toInitialize, {gas:8000000}); diff --git a/scripts/migrations/prod/6_setup_council_stakes.js b/scripts/migrations/prod/6_setup_council_stakes.js index 685a014..6aa8032 100644 --- a/scripts/migrations/prod/6_setup_council_stakes.js +++ b/scripts/migrations/prod/6_setup_council_stakes.js @@ -57,7 +57,13 @@ module.exports = async function(deployer) { await mainToken.approve(VaultProxy.address, T_TO_TRANSFER, {gas: 8000000}); - await stakingService.createLockWithoutEarlyWithdraw(T_TO_STAKE, LOCK_PERIOD, accounts[0], {gas: 600000}); - await stakingService.createLockWithoutEarlyWithdraw(T_TO_STAKE, LOCK_PERIOD, COUNCIL_1, {gas: 600000}); - await stakingService.createLockWithoutEarlyWithdraw(T_TO_STAKE, LOCK_PERIOD, COUNCIL_2, {gas: 600000}); + const AMOUNTS_TO_STAKE = [T_TO_STAKE, T_TO_STAKE, T_TO_STAKE] + const LOCK_PERIODS = [LOCK_PERIOD, LOCK_PERIOD, LOCK_PERIOD] + const COUNCILS = [accounts[0], COUNCIL_1, COUNCIL_2] + await stakingService.createLocksForCouncils( + AMOUNTS_TO_STAKE, + LOCK_PERIODS, + COUNCILS, + {gas: 8000000} + ); } \ No newline at end of file diff --git a/scripts/migrations/test/2_deploy_init_staking_proxy.js b/scripts/migrations/test/2_deploy_init_staking_proxy.js index e9873c3..fc74366 100644 --- a/scripts/migrations/test/2_deploy_init_staking_proxy.js +++ b/scripts/migrations/test/2_deploy_init_staking_proxy.js @@ -53,8 +53,6 @@ const maxWeightPenalty = 3000; const minWeightPenalty = 100; const weightMultiplier = 10; const maxNumberOfLocks = 10; -const maxOnBehalfLockPositions = 2; -const tau = 2; const lockingVoteWeight = 365 * 24 * 60 * 60; @@ -122,13 +120,9 @@ module.exports = async function(deployer) { { type: 'address', name: '_rewardsContract' - }, - { - type: 'uint256', - name: '_maxOnBehalfLockPositions' }] }, [MultiSigWallet.address, vaultService.address, MainToken.address, VMainToken.address, - weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address,maxOnBehalfLockPositions]); + weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address]); await deployer.deploy(StakingProxyAdmin, {gas:8000000}); await deployer.deploy(StakingProxy, StakingPackage.address, StakingProxyAdmin.address, toInitialize, {gas:8000000}); diff --git a/scripts/tests/dao/demo/staking.demo.test.js b/scripts/tests/dao/demo/staking.demo.test.js index 4062ae7..ba026d7 100644 --- a/scripts/tests/dao/demo/staking.demo.test.js +++ b/scripts/tests/dao/demo/staking.demo.test.js @@ -316,7 +316,7 @@ describe("Staking Test and Upgrade Test", () => { const unlockTime = lockingPeriod; console.log(".........Creating a Lock Position for staker 1........."); - let result = await stakingService.createLock(sumToDeposit,unlockTime, staker_1,{from: staker_1}); + let result = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_1}); // Since block time stamp can change after locking, we record the timestamp, // later to be used in the expectedNVFTHM calculation. // This mitigates an error created from the slight change in block time. @@ -351,7 +351,7 @@ describe("Staking Test and Upgrade Test", () => { const unlockTime = lockingPeriod; console.log(".........Creating a second Lock Position for staker 1........."); - let result = await stakingService.createLock(sumToDeposit, unlockTime, staker_1, {from: staker_1, gas:maxGasForTxn}); + let result = await stakingService.createLock(sumToDeposit, unlockTime, {from: staker_1, gas:maxGasForTxn}); let eventArgs = eventsHelper.getIndexedEventArgs(result, "Staked(address,uint256,uint256,uint256,uint256,uint256)"); const lockInfo = await stakingGetterService.getLockInfo(staker_1,2) @@ -390,9 +390,9 @@ describe("Staking Test and Upgrade Test", () => { await blockchain.mineBlock(await _getTimeStamp() + 20); console.log(".........Creating a Lock Position for staker 2 and Staker 3......."); - let result1 = await stakingService.createLock(sumToDepositForAll,unlockTime,staker_2, {from: staker_2}); + let result1 = await stakingService.createLock(sumToDepositForAll,unlockTime, {from: staker_2}); await blockchain.mineBlock(await _getTimeStamp() + 20); - let result2 = await stakingService.createLock(sumToDepositForAll,unlockTime, staker_3,{from: staker_3}); + let result2 = await stakingService.createLock(sumToDepositForAll,unlockTime,{from: staker_3}); await blockchain.mineBlock(await _getTimeStamp() + 20); let eventArgs1 = eventsHelper.getIndexedEventArgs(result1, "Staked(address,uint256,uint256,uint256,uint256,uint256)"); @@ -518,19 +518,6 @@ describe("Staking Test and Upgrade Test", () => { console.log(".........total Amount Of Stream Shares: ", totalAmountOfStreamShares.toString()); }); - it("Should not early unlock", async() => { - await FTHMToken.approve(vaultService.address, sumToApprove, {from: SYSTEM_ACC}) - let lockingPeriod = 365 * 24 * 60 * 60; - await stakingService.createLockWithoutEarlyWithdraw(sumToDeposit,lockingPeriod, staker_5,{from: SYSTEM_ACC}); - await blockchain.mineBlock(await _getTimeStamp() + 20); - const errorMessage = "early infeasible"; - - await shouldRevert( - stakingService.earlyUnlock(1, {from: staker_5}), - errTypes.revert, - errorMessage - ); - }) }); diff --git a/scripts/tests/dao/full-flow-demo.test.js b/scripts/tests/dao/full-flow-demo.test.js index 81d335e..0de26cf 100644 --- a/scripts/tests/dao/full-flow-demo.test.js +++ b/scripts/tests/dao/full-flow-demo.test.js @@ -137,22 +137,22 @@ const _encodeTransferFunction = (_account, t_to_stake) => { return toRet; } -const _encodeStakeFunction = (amount, lockPeriod, account, flag) => { +const _encodeStakeFunction = (amounts, lockPeriods, accounts) => { // encoded transfer function call for staking on behalf of someone else from treasury. let toRet = web3.eth.abi.encodeFunctionCall({ - name: 'createLockWithoutEarlyWithdraw', + name: 'createLocksForCouncils', type: 'function', inputs: [{ - type: 'uint256', - name: 'amount' + type: 'uint256[]', + name: 'amounts' },{ - type: 'uint256', - name: 'lockPeriod' + type: 'uint256[]', + name: 'lockPeriods' },{ - type: 'address', - name: 'account' + type: 'address[]', + name: 'accounts' }] - }, [amount, lockPeriod, account]); + }, [amounts, lockPeriods, accounts]); return toRet; } @@ -416,7 +416,7 @@ describe("DAO Demo", () => { let lockingPeriod = 365 * 24 * 60 * 60; const unlockTime = lockingPeriod; const beforeLockTimestamp = await _getTimeStamp() - let result = await stakingService.createLock(sumToDeposit,unlockTime, staker_1,{from: staker_1}); + let result = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_1}); lockingPeriod = lockingPeriod - (await _getTimeStamp() - beforeLockTimestamp); console.log(".........Total Staked Protocol Token Amount for Lock Position for a year", _convertToEtherBalance(sumToDeposit)); const expectedNVFTHM = _calculateNumberOfVFTHM(sumToDeposit, lockingPeriod, lockingVoteWeight) @@ -431,7 +431,7 @@ describe("DAO Demo", () => { let lockingPeriod = 365 * 24 * 60 * 60/2; const unlockTime = lockingPeriod; const beforeLockTimestamp = await _getTimeStamp() - let result = await stakingService.createLock(sumToDeposit,unlockTime,staker_1, {from: staker_1}); + let result = await stakingService.createLock(sumToDeposit,unlockTime, {from: staker_1}); console.log(".........Total Staked Protocol Token Amount for Lock Position for 1/2 a year", _convertToEtherBalance(sumToDeposit)); lockingPeriod = lockingPeriod - (await _getTimeStamp() - beforeLockTimestamp); const expectedNVFTHM = _calculateNumberOfVFTHM(sumToDeposit, lockingPeriod, lockingVoteWeight) @@ -453,9 +453,9 @@ describe("DAO Demo", () => { let lockingPeriod = 365 * 24 * 60 * 60; const unlockTime = lockingPeriod; - await stakingService.createLock(sumToDeposit,unlockTime, staker_2,{from: staker_2}); + await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_2}); await blockchain.increaseTime(20); - let result = await stakingService.createLock(sumToDeposit,unlockTime,staker_2, {from: staker_2}); + let result = await stakingService.createLock(sumToDeposit,unlockTime, {from: staker_2}); }); it("Should propose the first staking stream, stream - 1", async() => { @@ -533,7 +533,7 @@ describe("DAO Demo", () => { const unlockTime = lockingPeriod; let beforeLockTimestamp = await _getTimeStamp(); - await stakingService.createLock(sumToDeposit,unlockTime, staker_2,{from: staker_2,gas: maxGasForTxn}); + await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_2,gas: maxGasForTxn}); lockingPeriod = lockingPeriod - (await _getTimeStamp() - beforeLockTimestamp) const mineToTimestamp = 20 * 24 * 60 * 60 @@ -545,7 +545,7 @@ describe("DAO Demo", () => { const rewardsPeriodBN = new web3.utils.toBN(rewardsPeriod) const RewardProposalAmountForAStream = web3.utils.toWei('1000', 'ether'); - await stakingService.claimRewards(streamId,lockId,{from:staker_2, gas: maxGasForTxn}); + await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_2, gas: maxGasForTxn}); //Getting params from contracts to calculate the expected rewards: @@ -815,7 +815,8 @@ describe("DAO Demo", () => { it('Create proposal to send VC funds from MultiSig treasury to account 5', async() => { - + const eightHours = 28800 + await blockchain.mineBlock(await _getTimeStamp() + eightHours); // create a proposal in MainToken governor result = await mainTokenGovernor.propose( [multiSigWallet.address], @@ -959,25 +960,18 @@ describe("DAO Demo", () => { {"from": accounts[0]} ); txIndex3 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + const amounts = [amount,amount] + const lockPeriods = [oneYr,oneYr] + const commityAccounts = [comity_1,comity_2] let result2 = await multiSigWallet.submitTransaction( stakingService.address, EMPTY_BYTES, - _encodeStakeFunction(amount, oneYr, comity_1, true), + _encodeStakeFunction(amounts, lockPeriods, commityAccounts), 0, {"from": accounts[0]} ); txIndex5 = eventsHelper.getIndexedEventArgs(result2, SUBMIT_TRANSACTION_EVENT)[0]; - - let result_temp = await multiSigWallet.submitTransaction( - stakingService.address, - EMPTY_BYTES, - _encodeStakeFunction(amount, oneYr, comity_2, true), - 0, - {"from": accounts[0]} - ); - txIndex6 = eventsHelper.getIndexedEventArgs(result_temp, SUBMIT_TRANSACTION_EVENT)[0]; - }) it('Confirm and execute multiSig transactions to stake on behalf of comity', async() => { @@ -988,15 +982,11 @@ describe("DAO Demo", () => { await multiSigWallet.confirmTransaction(txIndex5, {"from": accounts[0]}); await multiSigWallet.confirmTransaction(txIndex5, {"from": accounts[1]}); - await multiSigWallet.confirmTransaction(txIndex6, {"from": accounts[0]}); - await multiSigWallet.confirmTransaction(txIndex6, {"from": accounts[1]}); - // execute: await multiSigWallet.executeTransaction(txIndex3, {"from": accounts[0]}); await blockchain.increaseTime(20); await multiSigWallet.executeTransaction(txIndex5, {"from": accounts[0]}); await blockchain.increaseTime(20); - await multiSigWallet.executeTransaction(txIndex6, {"from": accounts[0]}); }); it("Check that the lock possitions have been made on behalf of the comity", async() => { diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 0c9bf35..21466fb 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -56,6 +56,11 @@ const _encodeTransferFunction = (_account) => { return toRet; } +const _getTimeStamp = async () => { + const timestamp = await blockchain.getLatestBlockTimestamp() + return timestamp +} + describe('Proposal flow', () => { let timelockController @@ -207,7 +212,7 @@ describe('Proposal flow', () => { let unlockTime = lockingPeriod; - await stakingService.createLock(T_TO_STAKE, unlockTime, _account,{from: _account, gas: 600000}); + await stakingService.createLock(T_TO_STAKE, unlockTime,{from: _account, gas: 600000}); } it('Stake MainToken and receive vMainToken', async() => { @@ -433,11 +438,12 @@ describe('Proposal flow', () => { let unlockTime = lockingPeriod; - await stakingService.createLock(T_TO_STAKE, unlockTime, _account, {from: _account, gas: 600000}); + await stakingService.createLock(T_TO_STAKE, unlockTime, {from: _account, gas: 600000}); } it('Create proposal to send VC funds from MultiSig treasury to account 5', async() => { - + const eightHours = 28800 + await blockchain.mineBlock(await _getTimeStamp() + eightHours); // create a proposal in MainToken governor result = await mainTokenGovernor.propose( [multiSigWallet.address], diff --git a/scripts/tests/dao/governance/token-creation-though-gov.test.js b/scripts/tests/dao/governance/token-creation-though-gov.test.js index 28af5b2..2a278b2 100644 --- a/scripts/tests/dao/governance/token-creation-though-gov.test.js +++ b/scripts/tests/dao/governance/token-creation-though-gov.test.js @@ -172,7 +172,7 @@ describe('Token Creation Through Governance', () => { let unlockTime = lockingPeriod; - await stakingService.createLock(T_TO_STAKE, unlockTime, _account,{from: _account, gas: 600000}); + await stakingService.createLock(T_TO_STAKE, unlockTime,{from: _account, gas: 600000}); } it('Stake MainToken and receive vMainToken', async() => { diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index 86808be..f952ca0 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -354,7 +354,7 @@ describe("Staking Test", () => { let lockingPeriod = 24 * 60 * 60; const unlockTime = lockingPeriod; - let result = await stakingService.createLock(sumToDeposit,unlockTime, staker_1,{from: staker_1}); + let result = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_1}); // Since block time stamp can change after locking, we record the timestamp, // later to be used in the expectedNVFTHM calculation. // This mitigates an error created from the slight change in block time. @@ -384,7 +384,7 @@ describe("Staking Test", () => { let lockingPeriod = 24 * 60 * 60; const unlockTime = lockingPeriod; - let result = await stakingService.createLock(sumToDeposit,unlockTime,staker_1,{from: staker_1, gas:maxGasForTxn}); + let result = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_1, gas:maxGasForTxn}); let eventArgs = eventsHelper.getIndexedEventArgs(result, "Staked(address,uint256,uint256,uint256,uint256,uint256)"); const lockInfo = await stakingGetterService.getLockInfo(staker_1,2) @@ -422,11 +422,11 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + 20); - let result1 = await stakingService.createLock(sumToDepositForAll,unlockTime, staker_2,{from: staker_2}); + let result1 = await stakingService.createLock(sumToDepositForAll,unlockTime,{from: staker_2}); await blockchain.mineBlock(await _getTimeStamp() + 20); - let result2 = await stakingService.createLock(sumToDepositForAll,unlockTime, staker_3,{from: staker_3}); + let result2 = await stakingService.createLock(sumToDepositForAll,unlockTime,{from: staker_3}); await blockchain.mineBlock(await _getTimeStamp() + 20); - let result3 = await stakingService.createLock(sumToDepositForAll,unlockTime,staker_4, {from: staker_4}); + let result3 = await stakingService.createLock(sumToDepositForAll,unlockTime, {from: staker_4}); await blockchain.mineBlock(await _getTimeStamp() + 20); let eventArgs1 = eventsHelper.getIndexedEventArgs(result1, "Staked(address,uint256,uint256,uint256,uint256,uint256)"); @@ -454,7 +454,7 @@ describe("Staking Test", () => { it("Setup a third locked position with a 5 second lock period: LockId = 3 - staker_1", async() => { const unlockTime = 5; - let result = await stakingService.createLock(sumToDeposit,unlockTime,staker_1,{from: staker_1}); + let result = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_1}); await blockchain.mineBlock(await _getTimeStamp() + 20); }) @@ -724,9 +724,9 @@ describe("Staking Test", () => { const lockingPeriod = 20 * 24 * 60 * 60 const unlockTime = lockingPeriod; - await stakingService.createLock(sumToDeposit,unlockTime, staker_3,{from: staker_3,gas: maxGasForTxn}); + await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_3,gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 20); - await stakingService.createLock(sumToDeposit,unlockTime, staker_4,{from: staker_4,gas: maxGasForTxn}); + await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4,gas: maxGasForTxn}); }); @@ -737,7 +737,7 @@ describe("Staking Test", () => { const unlockTime = lockingPeriod; let beforeLockTimestamp = await _getTimeStamp(); - await stakingService.createLock(sumToDeposit,unlockTime, staker_2,{from: staker_2,gas: maxGasForTxn}); + await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_2,gas: maxGasForTxn}); const mineToTimestamp = 20 * 24 * 60 * 60 //21days await blockchain.mineBlock(beforeLockTimestamp + mineToTimestamp); @@ -775,7 +775,7 @@ describe("Staking Test", () => { const stream = 2; let result1 = await stakingService.claimAllLockRewardsForStream(stream,{from:staker_3, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 20); - let result2 = await stakingService.claimRewards(stream,lockId,{from:staker_4, gas: maxGasForTxn}); + let result2 = await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_4, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 20); let pendingRewards = (await stakingService.getUsersPendingRewards(staker_3, stream)).toString() @@ -791,9 +791,9 @@ describe("Staking Test", () => { const lockId = 1 const stream = 2; - await stakingService.claimRewards(stream,lockId,{from:staker_3, gas: maxGasForTxn}); + await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_3, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 20) - await stakingService.claimRewards(stream,lockId,{from:staker_4, gas: maxGasForTxn}); + await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_4, gas: maxGasForTxn}); let pendingRewards = (await stakingService.getUsersPendingRewards(staker_3, stream)).toString() console.log("pending rewards staker_3 - 2nd Claim: lockId -1",_convertToEtherBalance(pendingRewards)); pendingRewards = (await stakingService.getUsersPendingRewards(staker_4, stream)).toString() @@ -837,9 +837,9 @@ describe("Staking Test", () => { const lockingPeriod = 20 * 24 * 60 * 60 const unlockTime = lockingPeriod; - let result1 = await stakingService.createLock(sumToDeposit,unlockTime,staker_2, {from: staker_2, gas: maxGasForTxn}); + let result1 = await stakingService.createLock(sumToDeposit,unlockTime, {from: staker_2, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 100); - let result3 = await stakingService.createLock(sumToDeposit,unlockTime, staker_4,{from: staker_4, gas: maxGasForTxn}); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 100); }) @@ -849,7 +849,7 @@ describe("Staking Test", () => { const lockingPeriod_staker3 = 12 * 60 * 60 const unlockTime_staker3 = lockingPeriod_staker3 - let result2 = await stakingService.createLock(sumToDeposit,unlockTime_staker3,staker_3, {from: staker_3, gas: maxGasForTxn}); + let result2 = await stakingService.createLock(sumToDeposit,unlockTime_staker3, {from: staker_3, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 100); }) @@ -864,9 +864,9 @@ describe("Staking Test", () => { const claimableRewards_staker4 = await stakingService.getStreamClaimableAmountPerLock(streamId, staker_4, lockId); console.log("Claimable rewards for staker_3: ", _convertToEtherBalance(claimableRewards_staker3.toString())) console.log("Claimable rewards for staker_4: ", _convertToEtherBalance(claimableRewards_staker4.toString())) - let result1 = await stakingService.claimRewards(streamId,lockId,{from:staker_3, gas: maxGasForTxn}); + let result1 = await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_3, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 20); - let result2 = await stakingService.claimRewards(streamId,lockId,{from:staker_4, gas: maxGasForTxn}); + let result2 = await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_4, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 20); await stakingService.withdrawStream(streamId, {from:staker_3}) await stakingService.withdrawStream(streamId, {from:staker_4}) @@ -885,9 +885,9 @@ describe("Staking Test", () => { await blockchain.mineBlock(timestamp + mineToTimestamp); const lockId = 2 - let result1 = await stakingService.claimRewards(streamId,lockId,{from:staker_3, gas: maxGasForTxn}); + let result1 = await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_3, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 20); - let result2 = await stakingService.claimRewards(streamId,lockId,{from:staker_4, gas: maxGasForTxn}); + let result2 = await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_4, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 20); await stakingService.withdrawStream(streamId, {from:staker_3}) await stakingService.withdrawStream(streamId, {from:staker_4}) @@ -901,9 +901,9 @@ describe("Staking Test", () => { it('Setup 3rd and 4th locks for stakers _3', async() => { const lockingPeriod = 12 * 60 * 60 const unlockTime = lockingPeriod; - let result2 = await stakingService.createLock(sumToDeposit,unlockTime,staker_3, {from: staker_3,gas: maxGasForTxn}); + let result2 = await stakingService.createLock(sumToDeposit,unlockTime, {from: staker_3,gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 20); - let result3 = await stakingService.createLock(sumToDeposit,unlockTime, staker_3,{from: staker_3, gas: maxGasForTxn}); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_3, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 20); }) @@ -918,7 +918,7 @@ describe("Staking Test", () => { //lockId 3 rewards claimed await blockchain.mineBlock(timestamp + mineToTimestamp); - await stakingService.claimRewards(streamId,lockId,{from:staker_3}); + await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_3}); await blockchain.mineBlock(await _getTimeStamp() + mineToTimestamp); await stakingService.withdrawStream(streamId, {from: staker_3}) @@ -930,7 +930,7 @@ describe("Staking Test", () => { await blockchain.mineBlock(timestamp + mineToTimestamp); //lockId 3 rewards claimed - await stakingService.claimRewards(streamId,lockId,{from:staker_3}); + await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_3}); let pendingRewards = (await stakingService.getUsersPendingRewards(staker_3,streamId)).toString() console.log("pending rewards for lock Id 3 at first claim",_convertToEtherBalance(pendingRewards)); @@ -947,7 +947,7 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + mineToTimestamp); //so Now, the previous lockId 4 is lockId 3: - await stakingService.claimRewards(streamId,lockId,{from:staker_3}); + await stakingService.claimAllStreamRewardsForLock(lockId,{from:staker_3}); pendingRewards = (await stakingService.getUsersPendingRewards(staker_3,streamId)).toString() console.log("pending rewards for lockId 3 (previously 4) after unlocking:",_convertToEtherBalance(pendingRewards)); await blockchain.mineBlock(await _getTimeStamp() + mineToTimestamp); @@ -978,7 +978,7 @@ describe("Staking Test", () => { const streamId = 0 const lockingPeriod = 365 * 24 * 60 * 60; - await stakingService.createLock(sumToDeposit,lockingPeriod,staker_3, {from: staker_3,gas: maxGasForTxn}); + await stakingService.createLock(sumToDeposit,lockingPeriod,{from: staker_3,gas: maxGasForTxn}); await blockchain.mineBlock(60 * 60 + await _getTimeStamp()) const penalty = await stakingGetterService.getFeesForEarlyUnlock(lockId, staker_3); @@ -1098,7 +1098,7 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + 20) const lockingPeriod = 60 * 60 let unlockTime = lockingPeriod; - await stakingService.createLock(sumToDeposit,unlockTime,staker_3, {from: staker_3,gas: maxGasForTxn}); + await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_3,gas: maxGasForTxn}); await blockchain.mineBlock(10 + await _getTimeStamp()) await stakingService.earlyUnlock(lockId, {from: staker_3}) @@ -1120,7 +1120,7 @@ describe("Staking Test", () => { const lockingPeriod = 20 * 24 * 60 * 60 const unlockTime = lockingPeriod; await blockchain.mineBlock(await _getTimeStamp() + 100); - let result3 = await stakingService.createLock(sumToDeposit,unlockTime,staker_4, {from: staker_4, gas: maxGasForTxn}); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 100); }) @@ -1134,7 +1134,7 @@ describe("Staking Test", () => { const unlockTime = lockingPeriod; const sumToDeposit = web3.utils.toWei('20000', 'ether'); - let result1 = await stakingService.createLock(sumToDeposit,unlockTime,accounts[9], {from: accounts[9], gas: maxGasForTxn}); + let result1 = await stakingService.createLock(sumToDeposit,unlockTime, {from: accounts[9], gas: maxGasForTxn}); let eventArgs = eventsHelper.getIndexedEventArgs(result1, "Staked(address,uint256,uint256,uint256,uint256,uint256)"); const actualNVFTHM = web3.utils.toBN(eventArgs[1]) @@ -1212,7 +1212,7 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + 100); const errorMessage = "paused contract" await shouldRevert( - stakingService.createLock(sumToDeposit,unlockTime, staker_4,{from: staker_4, gas: maxGasForTxn}), + stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}), errTypes.revert, errorMessage ); @@ -1244,42 +1244,17 @@ describe("Staking Test", () => { const lockingPeriod = 20 * 24 * 60 * 60 const unlockTime = lockingPeriod; await blockchain.mineBlock(await _getTimeStamp() + 100); - let result3 = await stakingService.createLock(sumToDeposit,unlockTime,staker_4, {from: staker_4, gas: maxGasForTxn}); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime, {from: staker_4, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 100); }) it('Should should make lock position with 0 lock period', async() => { const unlockTime = 0; await blockchain.mineBlock(await _getTimeStamp() + 100); - let result3 = await stakingService.createLock(sumToDeposit,unlockTime, staker_4,{from: staker_4, gas: maxGasForTxn}); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}); await blockchain.mineBlock(await _getTimeStamp() + 100); }) - it('Should should make lock position on behalf', async() => { - const unlockTime = 0; - await blockchain.mineBlock(await _getTimeStamp() + 100); - let result3 = await stakingService.createLock(sumToDeposit,unlockTime, staker_4,{from: staker_3, gas: maxGasForTxn}); - await blockchain.mineBlock(await _getTimeStamp() + 100); - }) - - it('Should should make lock position on behalf', async() => { - const unlockTime = 0; - await blockchain.mineBlock(await _getTimeStamp() + 100); - let result3 = await stakingService.createLock(sumToDeposit,unlockTime, staker_4,{from: staker_3, gas: maxGasForTxn}); - await blockchain.mineBlock(await _getTimeStamp() + 100); - }) - - it('Should revert after max lock positions on behalf',async() => { - const unlockTime = 0; - await blockchain.mineBlock(await _getTimeStamp() + 100); - const errorMessage = "max lock on behalf"; - await shouldRevert( - stakingService.createLock(sumToDeposit,unlockTime, staker_4,{from: staker_3, gas: maxGasForTxn}), - errTypes.revert, - errorMessage - ) - await blockchain.mineBlock(await _getTimeStamp() + 100); - }) it('Should not be initalizable twice - Vault', async() => { From a8acb1e8c7ed6abc1a9239430306de1240285d9a Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 5 Jan 2023 12:38:32 +0545 Subject: [PATCH 19/77] adding changes for deploys --- .../prod/1_deploy_init_staking_proxy.js | 75 +++---------------- 1 file changed, 11 insertions(+), 64 deletions(-) diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index 096151a..a3a0791 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -72,9 +72,9 @@ module.exports = async function(deployer) { ); // const thirteenDecemberTimestampMidNight = 1670889600 - const EightThirtyPMUAETimestampTwelveDec = 1670862600; + const JanuarySixTweleveAMUAETime = 1672948800; - const startTime = EightThirtyPMUAETimestampTwelveDec; + const startTime = JanuarySixTweleveAMUAETime; const scheduleTimes = [ startTime, @@ -87,74 +87,21 @@ module.exports = async function(deployer) { startTime + 7 * oneDay, startTime + 8 * oneDay, startTime + 9 * oneDay, - startTime + 10 * oneDay, - startTime + 11 * oneDay, - startTime + 12 * oneDay, - startTime + 13 * oneDay, - startTime + 14 * oneDay, - startTime + 15 * oneDay, - startTime + 16 * oneDay, - startTime + 17 * oneDay, - startTime + 18 * oneDay, - startTime + 19 * oneDay, - startTime + 20 * oneDay, - startTime + 21 * oneDay, - startTime + 22 * oneDay, - startTime + 23 * oneDay, - startTime + 24 * oneDay, - startTime + 25 * oneDay, - startTime + 26 * oneDay, - startTime + 27 * oneDay, - startTime + 28 * oneDay, - startTime + 29 * oneDay, - startTime + 30 * oneDay, - startTime + 31 * oneDay, - startTime + 32 * oneDay, - startTime + 33 * oneDay, - startTime + 34 * oneDay, - startTime + 35 * oneDay, - startTime + 36 * oneDay, + startTime + 10 * oneDay ]; - const scheduleRewards = [ web3.utils.toWei('150000000', 'ether'), - web3.utils.toWei('140000000', 'ether'), - web3.utils.toWei('136000000', 'ether'), - web3.utils.toWei('132000000', 'ether'), - web3.utils.toWei('128000000', 'ether'), - web3.utils.toWei('124000000', 'ether'), + web3.utils.toWei('135000000', 'ether'), web3.utils.toWei('120000000', 'ether'), - web3.utils.toWei('116000000', 'ether'), - web3.utils.toWei('112000000', 'ether'), - web3.utils.toWei('108000000', 'ether'), - web3.utils.toWei('104000000', 'ether'), - web3.utils.toWei('100000000', 'ether'), - web3.utils.toWei('96000000', 'ether'), - web3.utils.toWei('92000000', 'ether'), - web3.utils.toWei('88000000', 'ether'), - web3.utils.toWei('84000000', 'ether'), - web3.utils.toWei('80000000', 'ether'), - web3.utils.toWei('76000000', 'ether'), - web3.utils.toWei('72000000', 'ether'), - web3.utils.toWei('68000000', 'ether'), - web3.utils.toWei('64000000', 'ether'), + web3.utils.toWei('105000000', 'ether'), + web3.utils.toWei('90000000', 'ether'), + web3.utils.toWei('75000000', 'ether'), web3.utils.toWei('60000000', 'ether'), - web3.utils.toWei('56000000', 'ether'), - web3.utils.toWei('52000000', 'ether'), - web3.utils.toWei('48000000', 'ether'), - web3.utils.toWei('44000000', 'ether'), - web3.utils.toWei('40000000', 'ether'), - web3.utils.toWei('36000000', 'ether'), - web3.utils.toWei('32000000', 'ether'), - web3.utils.toWei('28000000', 'ether'), - web3.utils.toWei('24000000', 'ether'), - web3.utils.toWei('20000000', 'ether'), - web3.utils.toWei('16000000', 'ether'), - web3.utils.toWei('12000000', 'ether'), - web3.utils.toWei('8000000', 'ether'), - web3.utils.toWei('4000000', 'ether'), - web3.utils.toWei("0", 'ether') + web3.utils.toWei('45000000', 'ether'), + web3.utils.toWei('30000000', 'ether'), + web3.utils.toWei('15000000', 'ether'), + web3.utils.toWei('0', 'ether') ]; const voteObject = _createVoteWeights( From a7d9ccabbc4a000d4594a85a727658250cd7c918 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 5 Jan 2023 17:06:42 +0545 Subject: [PATCH 20/77] finalizing audit fixes --- audit-report/Fathom_DAO.md | 46 +++++++++---------- contracts/dao/governance/Governor.sol | 5 +- .../dao/governance/TimelockController.sol | 2 +- contracts/dao/staking/StakingStorage.sol | 1 - contracts/dao/staking/StakingStructs.sol | 2 +- .../staking/helpers/StakingGettersHelper.sol | 1 - .../dao/staking/library/RewardsLibrary.sol | 2 +- .../staking/packages/RewardsCalculator.sol | 3 +- .../dao/staking/vault/interfaces/IVault.sol | 2 - .../staking/vault/packages/VaultPackage.sol | 7 +-- contracts/dao/tokens/VMainToken.sol | 2 - scripts/migrations/test/6_init_main_stream.js | 1 - 12 files changed, 32 insertions(+), 42 deletions(-) diff --git a/audit-report/Fathom_DAO.md b/audit-report/Fathom_DAO.md index 1c464d8..8213286 100644 --- a/audit-report/Fathom_DAO.md +++ b/audit-report/Fathom_DAO.md @@ -335,7 +335,7 @@ bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); ``` -#### [NEW] Transaction should be marked as `executed` if the call fails[DONE, understand more] +#### [NEW] Transaction should be marked as `executed` if the call fails[DONE, Ask] ##### Description @@ -681,7 +681,7 @@ https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6 We recommend limiting values of `scheduleTimes` or `scheduleRewards`.[NOTDONE] -#### [NEW] It is possible to remove tokens that are used by another contract in `VaultPackage`[NOTDONE] +#### [NEW] It is possible to remove tokens that are used by another contract in `VaultPackage`[DONE] ##### Description Calling the [`removeSupportedToken`]( @@ -694,7 +694,7 @@ We recommend adding logic to check that tokens are not used in any other contrac ### INFO -#### [NEW] There's no logging of reverted transactions in `MultiSigWallet` +#### [NEW] There's no logging of reverted transactions in `MultiSigWallet`[DONE] ##### Description In the function [`executeConfirmation`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L144) there's no logging of failed transactions. ```solidity @@ -718,7 +718,7 @@ if (success) { This will allow monitoring of suspicious activity that involves using of `MultiSigWallet`. -#### [NEW] Non-optimal packing of the `Transaction` structure in `MultiSigWallet` +#### [NEW] Non-optimal packing of the `Transaction` structure in `MultiSigWallet`[DONE] ##### Description The structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) uses a non-optimized storage layout. @@ -736,7 +736,7 @@ struct Transaction { } ``` -#### [NEW] Incorrect status check in `execute` function in `Governor` +#### [NEW] Incorrect status check in `execute` function in `Governor`[DONE] ##### Description In the [`execute`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) function there is an incorrect check of `Proposal` status: ```solidity @@ -749,14 +749,14 @@ We recommend changing the status check for `Proposal`: require(status == ProposalState.Queued, "Governor: proposal not successful"); ``` -#### [NEW] `_minDelay` can be set to zero in `TimelockController` +#### [NEW] `_minDelay` can be set to zero in `TimelockController`[NOTDONE] ##### Description In the `TimelockController` contract the `_minDelay` parameter can be set to `0` during [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L67) and in the [`updateDelay`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L149) function. This will result in batch being able to be executed in the same block it was queued for execution. ##### Recommendation We recommend adding a check that `_minDelay != 0`. -#### [NEW] There is a redundant `initialized` check in `VMainToken` +#### [NEW] There is a redundant `initialized` check in `VMainToken`[DONE] ##### Description ```solidity require(!initialized, "already init"); @@ -767,13 +767,13 @@ The [`initToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/ We recommend deleting these lines. -#### [NEW] There is redundant code in the `VMainToken` contract +#### [NEW] There is redundant code in the `VMainToken` contract[NOTDONE for future] ##### Description The [`_mint`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L74) and [`_burn`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L78) functions in the `VMainToken.sol` contract are redundant and essentially do not overload the parent functions. ##### Recommendation We recommend deleting these functions. -#### [NEW] The `Governor` and `TimeLockController` do not support the `ERC721` and `ERC1155` tokens +#### [NEW] The `Governor` and `TimeLockController` do not support the `ERC721` and `ERC1155` tokens[DOESNT REQUIRE] ##### Description The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contracts lack the following methods: @@ -821,7 +821,7 @@ Thus `Governor` and `TimeLockController` do not support tokens with `ERC721` and ##### Recommendation We recommend implementing these functions if the `Governor` and `TimeLockController` contracts require support for the `ERC721` and `ERC1155` tokens. And also create a list of trusted tokens that can work with (see above - `ERC20` standard tokens transfer possibility). -#### [NEW] The `addSupportedToken` and `removeSupportedToken` calls have an redundant `pausable` modifier in the `VaultPackage` contract +#### [NEW] The `addSupportedToken` and `removeSupportedToken` calls have an redundant `pausable` modifier in the `VaultPackage` contract[DONE] ##### Description In the `VaultPackage` contract the calls [`addSupportedToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L41) and [`removeSupportedToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L47) have a redundant modifier `pausable` since the calls are only possible from the `DEFAULT_ADMIN_ROLE` address and the modifier `pausable` contains the following condition ```solidity @@ -832,7 +832,7 @@ where the `paused` condition will be ignored. ##### Recommendation We recommend reconsidering the `addSupportedToken` and `removeSupportedToken` function modifiers or removing the `pausable` modifier. -#### [NEW] There are no checks that `admin`, `proposers` and `executors` are not zero addresses in `TimelockController` +#### [NEW] There are no checks that `admin`, `proposers` and `executors` are not zero addresses in `TimelockController`[NOTDONE] ##### Description @@ -854,7 +854,7 @@ We recommend adding checks that `admin`, `proposers` and `executors` are not zer We recommend removing it to keep the codebase clean. -#### [NEW] Unused constant `ONE_MONTH` in `StakingGettersHelper` +#### [NEW] Unused constant `ONE_MONTH` in `StakingGettersHelper`[DONE] ##### Description @@ -865,7 +865,7 @@ https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6 We recommend removing it to keep the codebase clean. -#### [NEW] Non-optimal storage layout for `Stream` struct in `StakingStructs` +#### [NEW] Non-optimal storage layout for `Stream` struct in `StakingStructs`[DONE] ##### Description @@ -889,7 +889,7 @@ struct Stream { } ``` -#### [NEW] Unnecessary `'` in a `RewardsLibrary` comment +#### [NEW] Unnecessary `'` in a `RewardsLibrary` comment[DONE] ##### Description There is an explicit `'` in the comment in [`RewardsLibrary.sol#L82`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L82) line. @@ -898,7 +898,7 @@ There is an explicit `'` in the comment in [`RewardsLibrary.sol#L82`](https://gi We recommend removing `'` from the comment. -#### [NEW] There is a typo in a comment in `StakingInternals` +#### [NEW] There is a typo in a comment in `StakingInternals`[DONE] ##### Description @@ -915,7 +915,7 @@ We recommend changing it to: // user does not have enough voteToken, it is still able to burn and unlock ``` -#### [NEW] Redundant check for `maxDepositAmount > 0` in `RewardsCalculator` +#### [NEW] Redundant check for `maxDepositAmount > 0` in `RewardsCalculator`[DONE] ##### Description @@ -931,7 +931,7 @@ Since `minDepositAmount` is already greater than `0` and `maxDepositAmount` must We recommend removing requirement of `maxDepositAmount > 0` for gas savings and improving code readability. -#### [NEW] It is not possible to withdraw tokens that were sent by mistake +#### [NEW] It is not possible to withdraw tokens that were sent by mistake[NOTDONE, no tokens are sent there] ##### Description @@ -947,14 +947,14 @@ It is not possible to withdraw tokens that were sent by mistake it the following We recommend adding `sweep` function to withdraw tokens that were sent by mistake. -#### [NEW] Unused import of `ReentracyGuard` in `StakingHandlers` +#### [NEW] Unused import of `ReentracyGuard` in `StakingHandlers`[DONE] ##### Description There is import of [`ReentracyGuard`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L11) in the `StakingHandlers` contract but `nonReentrant` from this class is never used in `StakingHandlers`. ##### Recommendation We recommend removing the unused import. -#### [NEW] Сustom `initializer` modifier is used instead of one from OpenZeppelin +#### [NEW] Сustom `initializer` modifier is used instead of one from OpenZeppelin[DONE] ##### Description @@ -969,7 +969,7 @@ It is better to use [Openzeppelin `initializer` ](https://github.com/OpenZeppeli We recommend using `initializer` and `initializable` modifiers from Openzeppelin instead of implementing custom modifiers. -#### [NEW] Stream manager, treasury manager and admin represent the same account in `StakingHandlers` +#### [NEW] Stream manager, treasury manager and admin represent the same account in `StakingHandlers`[NTDONE] ##### Description @@ -979,7 +979,7 @@ In the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart We recommend to transfer treasury role after the deployment and the staking setting. Admin and manager of the initial `stream` should be two different roles. -#### [NEW] Revert message strings are too long +#### [NEW] Revert message strings are too long[NTDONE] ##### Description @@ -1001,7 +1001,7 @@ We recommend making revert strings shorter. Note that if your contracts already allow Solidity `0.8.4` and above, then consider using [custom errors](https://blog.soliditylang.org/2021/04/21/custom-errors). They provide more gas efficiency and also allow developers to describe the errors in detail using [NatSpec](https://docs.soliditylang.org/en/latest/natspec-format.html). The main disadvantage of this approach is that some tooling may not have proper support for it yet. -#### [NEW] Unnecessary reads from storage +#### [NEW] Unnecessary reads from storage[DONE for applicable] ##### Description @@ -1020,7 +1020,7 @@ In the next lines using `MLOAD` and `MSTORE` to cache the variable in `memory` s We recommend caching this storage variable in `memory` to reduce unnecessary reads from storage and save more gas. -#### [NEW] Misleading check `(scheduleTimeLength > 0)` in the `RewardsCalculator` +#### [NEW] Misleading check `(scheduleTimeLength > 0)` in the `RewardsCalculator`[DONE] ##### Description diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index f54fd43..7cbda70 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -99,7 +99,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { requireConfirmed(proposalId); ProposalState status = state(proposalId); - require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); + require(status == ProposalState.Queued, "Governor: proposal not successful"); uint256 totalValue = 0; for (uint256 i = 0;i < values.length; i++){ totalValue += values[i]; @@ -385,7 +385,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { function _countVote(uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory params) internal virtual; function _execute( - uint256 /* proposalId */, + uint256 /*proposalId*/ , address[] memory targets, uint256[] memory values, bytes[] memory calldatas, @@ -398,6 +398,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { } } + function _beforeExecute( uint256 /* proposalId */, address[] memory targets, diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index 4c67b15..2f5842f 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -109,7 +109,7 @@ contract TimelockController is AccessControl, Initializable, ITimelockController emit Cancelled(id); } - //TODO + function execute( address target, uint256 value, diff --git a/contracts/dao/staking/StakingStorage.sol b/contracts/dao/staking/StakingStorage.sol index 2dbc725..3a53328 100644 --- a/contracts/dao/staking/StakingStorage.sol +++ b/contracts/dao/staking/StakingStorage.sol @@ -4,7 +4,6 @@ pragma solidity 0.8.13; -import "./StakingStructs.sol"; import "./interfaces/IStakingStorage.sol"; import "./library/StakingLibrary.sol"; diff --git a/contracts/dao/staking/StakingStructs.sol b/contracts/dao/staking/StakingStructs.sol index feb3e09..583c867 100644 --- a/contracts/dao/staking/StakingStructs.sol +++ b/contracts/dao/staking/StakingStructs.sol @@ -55,6 +55,7 @@ struct Stream { address owner; // stream owned by the ERC-20 reward token owner address manager; // stream manager handled by Main stream manager role address rewardToken; + StreamStatus status; uint256 rewardDepositAmount; // the reward amount that has been deposited by third party uint256 rewardClaimedAmount; /// how much rewards have been claimed by stakers uint256 maxDepositAmount; // maximum amount of deposit @@ -62,5 +63,4 @@ struct Stream { uint256 tau; // pending time prior reward release uint256 rps; // Reward per share for a stream j>0 Schedule schedule; - StreamStatus status; } diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index f8c14e4..dc96980 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -10,7 +10,6 @@ import "../../../common/access/AccessControl.sol"; contract StakingGettersHelper is IStakingGetterHelper, AccessControl { address private stakingContract; - uint256 internal constant ONE_MONTH = 2629746; uint256 internal constant ONE_YEAR = 31536000; uint256 internal constant WEEK = 604800; diff --git a/contracts/dao/staking/library/RewardsLibrary.sol b/contracts/dao/staking/library/RewardsLibrary.sol index 8dab3e8..0fd72ca 100644 --- a/contracts/dao/staking/library/RewardsLibrary.sol +++ b/contracts/dao/staking/library/RewardsLibrary.sol @@ -79,7 +79,7 @@ library RewardsLibrary { // Here reward = from end of start schedule till beginning of end schedule // Reward during the period from startIndex + 1 to endIndex rewardScheduledAmount += schedule.reward[startIndex + 1] - schedule.reward[endIndex]; - // Reward at the end schedule where schedule.time[endIndex] ' + // Reward at the end schedule where schedule.time[endIndex] reward = schedule.reward[endIndex] - schedule.reward[endIndex + 1]; rewardScheduledAmount += (reward * (end - schedule.time[endIndex])) / (schedule.time[endIndex + 1] - schedule.time[endIndex]); } diff --git a/contracts/dao/staking/packages/RewardsCalculator.sol b/contracts/dao/staking/packages/RewardsCalculator.sol index e98c005..1061902 100644 --- a/contracts/dao/staking/packages/RewardsCalculator.sol +++ b/contracts/dao/staking/packages/RewardsCalculator.sol @@ -18,7 +18,6 @@ contract RewardsCalculator is IRewardsHandler { ) public view override { require(streamOwner != address(0), "bad owner"); require(rewardToken != address(0), "bad reward token"); - require(maxDepositAmount > 0, "No Max Deposit"); require(minDepositAmount > 0, "No Min Deposit"); require(minDepositAmount <= maxDepositAmount, "bad Min Deposit"); require(maxDepositAmount == scheduleRewards[0], "Invalid Max Deposit"); @@ -91,7 +90,7 @@ contract RewardsCalculator is IRewardsHandler { uint256 end ) internal pure returns (uint256 startIndex, uint256 endIndex) { uint256 scheduleTimeLength = schedule.time.length; - require(scheduleTimeLength > 0, "bad schedules"); + require(scheduleTimeLength >=2, "bad schedules"); require(end > start, "bad query period"); require(start >= schedule.time[0], "query before start"); require(end <= schedule.time[scheduleTimeLength - 1], "query after end"); diff --git a/contracts/dao/staking/vault/interfaces/IVault.sol b/contracts/dao/staking/vault/interfaces/IVault.sol index 471963e..99d3381 100644 --- a/contracts/dao/staking/vault/interfaces/IVault.sol +++ b/contracts/dao/staking/vault/interfaces/IVault.sol @@ -13,8 +13,6 @@ interface IVault { function removeSupportedToken(address _token) external; function payRewards(address _user, address _token, uint256 _deposit) external; - - function emergencyStop() external; function migrate(address vaultPackageMigrateTo) external; diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index e3f0fdc..ed898e0 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -55,13 +55,13 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { /// supported tokens means any future stream token should be /// whitelisted here /// @param _token stream ERC20 token address - function addSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) pausable(1) { + function addSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) { _addSupportedToken(_token); } /// @notice removed token as a supproted rewards token by Treasury /// @param _token stream ERC20 token address - function removeSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) pausable(1) { + function removeSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) { require(isSupportedToken[_token], "Token does not exist"); require(deposited[_token] == 0,"Token is still in use"); isSupportedToken[_token] = false; @@ -69,9 +69,6 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { emit TokenRemoved(_token, msg.sender, block.timestamp); } - function emergencyStop() external override { - _adminPause(1); - } function migrate(address newVaultPackage) external override onlyRole(DEFAULT_ADMIN_ROLE){ require(!migrated,"vault already migrated"); diff --git a/contracts/dao/tokens/VMainToken.sol b/contracts/dao/tokens/VMainToken.sol index a8a0c42..d1d8be4 100644 --- a/contracts/dao/tokens/VMainToken.sol +++ b/contracts/dao/tokens/VMainToken.sol @@ -22,8 +22,6 @@ contract VMainToken is IVMainToken, Pausable, AccessControl, Initializable, ERC2 } function initToken(address _admin, address _minter) public override initializer onlyRole(DEFAULT_ADMIN_ROLE) { - require(!initialized, "already init"); - initialized = true; require(_admin != msg.sender, "initToken: Admin should be different than msg.sender"); _grantRole(DEFAULT_ADMIN_ROLE, _admin); _grantRole(PAUSER_ROLE, _admin); diff --git a/scripts/migrations/test/6_init_main_stream.js b/scripts/migrations/test/6_init_main_stream.js index 3e933be..0a56c74 100644 --- a/scripts/migrations/test/6_init_main_stream.js +++ b/scripts/migrations/test/6_init_main_stream.js @@ -8,7 +8,6 @@ const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') const blockchain = require("../../tests/helpers/blockchain"); const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') -//TODO: Do it in prod script const _getTimeStamp = async () => { const timestamp = await blockchain.getLatestBlockTimestamp(); return timestamp; From b0bc2a14f229a104ff737afdaf5f065f15291291 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 5 Jan 2023 18:44:10 +0545 Subject: [PATCH 21/77] deploy steps --- contracts/dao/governance/Governor.sol | 1 - scripts/migrations/prod/1_deploy_init_staking_proxy.js | 4 ++-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index ca9b9ed..54afae0 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -403,7 +403,6 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); uint256 weight = _getVotes(account, proposal.voteStart.getDeadline(), params); - require(weight>0, "vFTHM balance is 0"); _countVote(proposalId, account, support, weight, params); if (params.length == 0) { diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index a3a0791..8bab206 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -72,9 +72,9 @@ module.exports = async function(deployer) { ); // const thirteenDecemberTimestampMidNight = 1670889600 - const JanuarySixTweleveAMUAETime = 1672948800; + const JanuaryFiveEIGHTPMUAE = 1672934400; - const startTime = JanuarySixTweleveAMUAETime; + const startTime = JanuaryFiveEIGHTPMUAE; const scheduleTimes = [ startTime, From f798e918db6ab995fed1a015816d1a54c530c863 Mon Sep 17 00:00:00 2001 From: ssubik Date: Fri, 6 Jan 2023 18:17:50 +0545 Subject: [PATCH 22/77] adding audit fixes --- contracts/common/math/FullMath.sol | 128 ++++++++ contracts/dao/governance/Governor.sol | 2 +- .../dao/governance/TimelockController.sol | 11 +- contracts/dao/staking/StakingStructs.sol | 6 + .../staking/interfaces/IStakingHandler.sol | 3 +- .../staking/packages/RewardsCalculator.sol | 8 +- .../dao/staking/packages/StakingHandler.sol | 17 +- .../dao/staking/packages/StakingInternals.sol | 2 +- .../staking/vault/packages/VaultPackage.sol | 4 +- contracts/dao/tokens/VMainToken.sol | 8 - .../migrations/prod/6_setup_council_stakes.js | 77 +++-- .../dao/governance/proposal-flow.test.js | 297 +++++++++++++++++- 12 files changed, 512 insertions(+), 51 deletions(-) create mode 100644 contracts/common/math/FullMath.sol diff --git a/contracts/common/math/FullMath.sol b/contracts/common/math/FullMath.sol new file mode 100644 index 0000000..ff691fd --- /dev/null +++ b/contracts/common/math/FullMath.sol @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.0; + +/// @title Contains 512-bit math functions +/// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision +/// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits +library FullMath { + /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 + /// @param a The multiplicand + /// @param b The multiplier + /// @param denominator The divisor + /// @return result The 256-bit result + /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv + function mulDiv( + uint256 a, + uint256 b, + uint256 denominator + ) internal pure returns (uint256 result) { + unchecked { + // 512-bit multiply [prod1 prod0] = a * b + // Compute the product mod 2**256 and mod 2**256 - 1 + // then use the Chinese Remainder Theorem to reconstruct + // the 512 bit result. The result is stored in two 256 + // variables such that product = prod1 * 2**256 + prod0 + uint256 prod0; // Least significant 256 bits of the product + uint256 prod1; // Most significant 256 bits of the product + assembly { + let mm := mulmod(a, b, not(0)) + prod0 := mul(a, b) + prod1 := sub(sub(mm, prod0), lt(mm, prod0)) + } + + // Handle non-overflow cases, 256 by 256 division + if (prod1 == 0) { + require(denominator > 0); + assembly { + result := div(prod0, denominator) + } + return result; + } + + // Make sure the result is less than 2**256. + // Also prevents denominator == 0 + require(denominator > prod1); + + /////////////////////////////////////////////// + // 512 by 256 division. + /////////////////////////////////////////////// + + // Make division exact by subtracting the remainder from [prod1 prod0] + // Compute remainder using mulmod + uint256 remainder; + assembly { + remainder := mulmod(a, b, denominator) + } + // Subtract 256 bit number from 512 bit number + assembly { + prod1 := sub(prod1, gt(remainder, prod0)) + prod0 := sub(prod0, remainder) + } + + // Factor powers of two out of denominator + // Compute largest power of two divisor of denominator. + // Always >= 1. + uint256 twos = (0 - denominator) & denominator; + // Divide denominator by power of two + assembly { + denominator := div(denominator, twos) + } + + // Divide [prod1 prod0] by the factors of two + assembly { + prod0 := div(prod0, twos) + } + // Shift in bits from prod1 into prod0. For this we need + // to flip `twos` such that it is 2**256 / twos. + // If twos is zero, then it becomes one + assembly { + twos := add(div(sub(0, twos), twos), 1) + } + prod0 |= prod1 * twos; + + // Invert denominator mod 2**256 + // Now that denominator is an odd number, it has an inverse + // modulo 2**256 such that denominator * inv = 1 mod 2**256. + // Compute the inverse by starting with a seed that is correct + // correct for four bits. That is, denominator * inv = 1 mod 2**4 + uint256 inv = (3 * denominator) ^ 2; + // Now use Newton-Raphson iteration to improve the precision. + // Thanks to Hensel's lifting lemma, this also works in modular + // arithmetic, doubling the correct bits in each step. + inv *= 2 - denominator * inv; // inverse mod 2**8 + inv *= 2 - denominator * inv; // inverse mod 2**16 + inv *= 2 - denominator * inv; // inverse mod 2**32 + inv *= 2 - denominator * inv; // inverse mod 2**64 + inv *= 2 - denominator * inv; // inverse mod 2**128 + inv *= 2 - denominator * inv; // inverse mod 2**256 + + // Because the division is now exact we can divide by multiplying + // with the modular inverse of denominator. This will give us the + // correct result modulo 2**256. Since the precoditions guarantee + // that the outcome is less than 2**256, this is the final result. + // We don't need to compute the high bits of the result and prod1 + // is no longer required. + result = prod0 * inv; + return result; + } + } + + /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 + /// @param a The multiplicand + /// @param b The multiplier + /// @param denominator The divisor + /// @return result The 256-bit result + function mulDivRoundingUp( + uint256 a, + uint256 b, + uint256 denominator + ) internal pure returns (uint256 result) { + unchecked { + result = mulDiv(a, b, denominator); + if (mulmod(a, b, denominator) > 0) { + require(result < type(uint256).max); + result++; + } + } + } +} \ No newline at end of file diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 7cbda70..18ea22f 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -231,7 +231,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { function updateProposalTimeDelay(uint256 newProposalTimeDelay) public onlyMultiSig { require(newProposalTimeDelay != 0,"updateProposalTimeDelay: newProposalTimeDelay cant be zero"); - emit MaxTargetUpdated(newProposalTimeDelay, proposalTimeDelay); + emit ProposalTimeDelayUpdated(newProposalTimeDelay, proposalTimeDelay); proposalTimeDelay = newProposalTimeDelay; } diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index 2f5842f..f84ec45 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -47,6 +47,8 @@ contract TimelockController is AccessControl, Initializable, ITimelockController } function initialize(uint256 minDelay, address admin, address[] memory proposers, address[] memory executors) public override initializer { + require(minDelay!=0,"minDelay should be greater than zero"); + require(admin!=address(0),"admin should not be zero address"); _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE); _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE); _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE); @@ -58,11 +60,13 @@ contract TimelockController is AccessControl, Initializable, ITimelockController _grantRole(DEFAULT_ADMIN_ROLE, admin); for (uint256 i = 0; i < proposers.length; ++i) { + require(proposers[i] !=address(0),"proposer should not be zero address"); _setupRole(PROPOSER_ROLE, proposers[i]); _setupRole(CANCELLER_ROLE, proposers[i]); } for (uint256 i = 0; i < executors.length; ++i) { + require(executors[i] !=address(0),"executor should not be zero address"); _setupRole(EXECUTOR_ROLE, executors[i]); } @@ -118,11 +122,15 @@ contract TimelockController is AccessControl, Initializable, ITimelockController bytes32 salt ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) { bytes32 id = hashOperation(target, value, payload, predecessor, salt); - + require(msg.value >= value,"execute: msg.value insufficient sent"); _beforeCall(id, predecessor); _execute(target, value, payload); emit CallExecuted(id, 0, target, value, payload); _afterCall(id); + if(msg.value > value){ + (bool sent, ) = msg.sender.call{value: (msg.value - value)}(""); + require(sent, "Failed to send ether"); + } } function executeBatch( @@ -150,6 +158,7 @@ contract TimelockController is AccessControl, Initializable, ITimelockController function updateDelay(uint256 newDelay) public virtual { require(msg.sender == address(this), "TimelockController: caller must be timelock"); + require(newDelay>0,"new delay should be greater than zero"); emit MinDelayChange(_minDelay, newDelay); _minDelay = newDelay; } diff --git a/contracts/dao/staking/StakingStructs.sol b/contracts/dao/staking/StakingStructs.sol index 583c867..e0fa371 100644 --- a/contracts/dao/staking/StakingStructs.sol +++ b/contracts/dao/staking/StakingStructs.sol @@ -64,3 +64,9 @@ struct Stream { uint256 rps; // Reward per share for a stream j>0 Schedule schedule; } + +struct CreateLockParams{ + uint256 amount; + uint256 lockPeriod; + address account; + } diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index bbed999..106720d 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -42,7 +42,6 @@ interface IStakingHandler { function createLock(uint256 amount, uint256 lockPeriod) external; - function unlockPartially(uint256 lockId, uint256 amount) external; function unlock(uint256 lockId) external; @@ -61,5 +60,5 @@ interface IStakingHandler { function updateVault(address _vault) external; function emergencyUnlockAndWithdraw() external; - function createLocksForCouncils(uint256[] memory amounts, uint256[] memory lockPeriods, address[] memory accounts) external; + function createLocksForCouncils(CreateLockParams[] calldata lockParams) external; } diff --git a/contracts/dao/staking/packages/RewardsCalculator.sol b/contracts/dao/staking/packages/RewardsCalculator.sol index 1061902..6bd1144 100644 --- a/contracts/dao/staking/packages/RewardsCalculator.sol +++ b/contracts/dao/staking/packages/RewardsCalculator.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.13; import "../StakingStructs.sol"; import "../interfaces/IRewardsHandler.sol"; +import "../../../common/math/FullMath.sol"; contract RewardsCalculator is IRewardsHandler { // solhint-disable not-rely-on-time @@ -66,6 +67,9 @@ contract RewardsCalculator is IRewardsHandler { if (startIndex == endIndex) { // start and end are within the same schedule period reward = schedule.reward[startIndex] - schedule.reward[startIndex + 1]; + rewardScheduledAmount = FullMath.mulDiv( + reward, (end - start), + (schedule.time[startIndex + 1] - schedule.time[startIndex])); rewardScheduledAmount = (reward * (end - start)) / (schedule.time[startIndex + 1] - schedule.time[startIndex]); } else { // start and end are not within the same schedule period @@ -79,7 +83,9 @@ contract RewardsCalculator is IRewardsHandler { rewardScheduledAmount += schedule.reward[startIndex + 1] - schedule.reward[endIndex]; // Reward at the end schedule where schedule.time[endIndex] ' reward = schedule.reward[endIndex] - schedule.reward[endIndex + 1]; - rewardScheduledAmount += (reward * (end - schedule.time[endIndex])) / (schedule.time[endIndex + 1] - schedule.time[endIndex]); + rewardScheduledAmount += FullMath.mulDiv(reward, + (end - schedule.time[endIndex]), + (schedule.time[endIndex + 1] - schedule.time[endIndex])); } return rewardScheduledAmount; } diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 6771680..35429b8 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -33,7 +33,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A address _mainToken, address _voteToken, Weight calldata _weight, - VoteCoefficient memory voteCoef, + VoteCoefficient calldata voteCoef, uint256 _maxLocks, address _rewardsContract ) external override initializer{ @@ -180,19 +180,14 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } function createLocksForCouncils( - uint256[] memory amounts, - uint256[] memory lockPeriods, - address[] memory accounts) public override + CreateLockParams[] calldata lockParams) public override onlyRole(DEFAULT_ADMIN_ROLE) { require(!councilsInitialized,"already created"); - require( - amounts.length == lockPeriods.length - && amounts.length == lockPeriods.length,"bad len"); - councilsInitialized = true; - for(uint i = 0; i < amounts.length; i++){ - prohibitedEarlyWithdraw[accounts[i]][locks[accounts[i]].length + 1] = true; - _createLock(amounts[i], lockPeriods[i], accounts[i]); + for(uint i = 0; i < lockParams.length; i++){ + address account = lockParams[i].account; + prohibitedEarlyWithdraw[account][locks[account].length + 1] = true; + _createLock(lockParams[i].amount, lockParams[i].lockPeriod, account); } } diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 09caa27..c708227 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -30,7 +30,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { require(_weight.maxWeightShares > _weight.minWeightShares, "bad share"); require(_weight.maxWeightPenalty > _weight.minWeightPenalty, "bad penalty"); require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "wrong weight"); - + require(_voteLockCoef!=0,"zero coef"); mainToken = _mainToken; voteToken = _voteToken; weight = _weight; diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index ed898e0..e32a3d5 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -38,7 +38,6 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "payRewards: No role"); require(isSupportedToken[_token], "Unsupported token"); require(_amount!=0,"amount zero"); - require(IERC20(_token).balanceOf(address(this))>=_amount,"not enough balance"); require(deposited[_token] >= _amount,"payRewards: not enough deposit"); deposited[_token] -= _amount; IERC20(_token).safeTransfer(_user,_amount); @@ -69,7 +68,7 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { emit TokenRemoved(_token, msg.sender, block.timestamp); } - + /// @notice we believe newVaultPackage is safe function migrate(address newVaultPackage) external override onlyRole(DEFAULT_ADMIN_ROLE){ require(!migrated,"vault already migrated"); require(paused != 0, "required pause"); @@ -78,6 +77,7 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { { address token = listOfSupportedTokens[i]; uint256 balance = IERC20(token).balanceOf(address(this)); + deposited[token] = 0; IERC20(token).safeApprove(newVaultPackage,balance); IVault(newVaultPackage).deposit(address(this), listOfSupportedTokens[i],balance); } diff --git a/contracts/dao/tokens/VMainToken.sol b/contracts/dao/tokens/VMainToken.sol index d1d8be4..39b624f 100644 --- a/contracts/dao/tokens/VMainToken.sol +++ b/contracts/dao/tokens/VMainToken.sol @@ -78,12 +78,4 @@ contract VMainToken is IVMainToken, Pausable, AccessControl, Initializable, ERC2 function _afterTokenTransfer(address from, address to, uint256 amount) internal override { super._afterTokenTransfer(from, to, amount); } - - function _mint(address to, uint256 amount) internal override { - super._mint(to, amount); - } - - function _burn(address account, uint256 amount) internal override { - super._burn(account, amount); - } } diff --git a/scripts/migrations/prod/6_setup_council_stakes.js b/scripts/migrations/prod/6_setup_council_stakes.js index 6aa8032..34f96f6 100644 --- a/scripts/migrations/prod/6_setup_council_stakes.js +++ b/scripts/migrations/prod/6_setup_council_stakes.js @@ -21,14 +21,23 @@ const COUNCIL_2 = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') - -const _encodeTransferFunction = (_account, _amount) => { +const _createLockParamObject = ( + _amount, + _lockPeriod, + _account) => { + return { + amount: _amount, + lockPeriod: _lockPeriod, + account: _account + } +} +const _encodeApproveFunction = (_account, _amount) => { let toRet = web3.eth.abi.encodeFunctionCall({ - name: 'transfer', + name: 'approve', type: 'function', inputs: [{ type: 'address', - name: 'to' + name: 'spender' },{ type: 'uint256', name: 'amount' @@ -38,32 +47,56 @@ const _encodeTransferFunction = (_account, _amount) => { return toRet; } +const _encodeCreateLocksForCouncils = (_createLockParam) => { + let toRet = web3.eth.abi.encodeFunctionCall({ + name:'createLocksForCouncils', + type:'function', + inputs: [{ + type: 'tuple[]', + name: 'CreateLockParams', + components: [ + {"type":"uint256", "name":"amount"}, + {"type":"uint256", "name":"lockPeriod"}, + {"type":"address", "name":"account"} + ] + } + ] + },[_createLockParam]) + return toRet +} + module.exports = async function(deployer) { const stakingService = await IStaking.at(StakingProxy.address); const multiSigWallet = await IMultiSigWallet.at(MultiSigWallet.address); const mainToken = await IERC20.at(MainToken.address); - let result = await multiSigWallet.submitTransaction( - MainToken.address, - EMPTY_BYTES, - _encodeTransferFunction(accounts[0], T_TO_TRANSFER), + let resultApprove = await multiSigWallet.submitTransaction( + MainToken.address, + EMPTY_BYTES, + _encodeApproveFunction(VaultProxy.address,T_TO_TRANSFER), 0, {gas: 8000000} - ); - let txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + ) + + let txIndexApprove = eventsHelper.getIndexedEventArgs(resultApprove, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(txIndexApprove, {gas: 8000000}); + await multiSigWallet.executeTransaction(txIndexApprove, {gas: 8000000}); - await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); - await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); + const LockParamObjectForAllCouncils = [ + _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,accounts[0]), + _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,COUNCIL_1), + _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,COUNCIL_2) + ] - await mainToken.approve(VaultProxy.address, T_TO_TRANSFER, {gas: 8000000}); - - const AMOUNTS_TO_STAKE = [T_TO_STAKE, T_TO_STAKE, T_TO_STAKE] - const LOCK_PERIODS = [LOCK_PERIOD, LOCK_PERIOD, LOCK_PERIOD] - const COUNCILS = [accounts[0], COUNCIL_1, COUNCIL_2] - await stakingService.createLocksForCouncils( - AMOUNTS_TO_STAKE, - LOCK_PERIODS, - COUNCILS, + let resultCreateLock = await multiSigWallet.submitTransaction( + stakingService.address, + EMPTY_BYTES, + _encodeCreateLocksForCouncils(LockParamObjectForAllCouncils), + 0, {gas: 8000000} - ); + ) + + let txIndexCreateLock = eventsHelper.getIndexedEventArgs(resultCreateLock, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(txIndexCreateLock, {gas: 8000000}); + await multiSigWallet.executeTransaction(txIndexCreateLock, {gas: 8000000}); } \ No newline at end of file diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 21466fb..25e08f4 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -33,7 +33,9 @@ const _encodeConfirmation = async (_proposalId) => { const T_TO_STAKE = web3.utils.toWei('2000', 'ether'); const STAKED_MIN = web3.utils.toWei('1900', 'ether'); - +let streamReward1; +let proposalIdForAddingSupportedToken; +let proposalIdForRelayFunction const STAKER_1 = accounts[5]; const STAKER_2 = accounts[6]; const NOT_STAKER = accounts[7]; @@ -77,6 +79,7 @@ describe('Proposal flow', () => { let encoded_function let encoded_transfer_function let encoded_treasury_function + let encoded_relay_function let description_hash let description_hash_2 @@ -85,6 +88,8 @@ describe('Proposal flow', () => { let txIndex2 let lockingPeriod; + let encoded_function_add_supporting_token; + let encoded_function_relay; before(async () => { @@ -95,7 +100,7 @@ describe('Proposal flow', () => { box = await artifacts.initializeInterfaceAt("Box", "Box"); FTHMToken = await artifacts.initializeInterfaceAt("MainToken", "MainToken"); multiSigWallet = await artifacts.initializeInterfaceAt("MultiSigWallet", "MultiSigWallet"); - + streamReward1 = await artifacts.initializeInterfaceAt("ERC20Rewards2","ERC20Rewards2"); stakingService = await artifacts.initializeInterfaceAt( "IStaking", "StakingProxy" @@ -632,6 +637,294 @@ describe('Proposal flow', () => { await _stakeMainGetVe(accounts[9]); }); + + it('Propose to add supporting Token', async() => { + const eightHours = 28800 + await blockchain.increaseTime(eightHours) + encoded_function_add_supporting_token = web3.eth.abi.encodeFunctionCall({ + name: 'addSupportingToken', + type: 'function', + inputs: [{ + type: 'address', + name: '_token' + }] + }, [streamReward1.address]); + // create a proposal in MainToken governor + result = await mainTokenGovernor.propose( + [mainTokenGovernor.address], + [0], + [encoded_function_add_supporting_token], + PROPOSAL_DESCRIPTION, + {"from": STAKER_1} + ); + // retrieve the proposal id + proposalIdForAddingSupportedToken = eventsHelper.getIndexedEventArgs(result, PROPOSAL_CREATED_EVENT)[0]; + }); + + it('Wait two blocks and then check that the proposal status is: Active', async() => { + + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 2) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + // Check that the proposal is open for voting + expect((await mainTokenGovernor.state(proposalIdForAddingSupportedToken)).toString()).to.equal("1"); + }); + + it('Vote on the proposal', async() => { + + // enum VoteType { + // Against, + // For, + // Abstain + // } + // => 0 = Against, 1 = For, 2 = Abstain + + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 2) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + // Vote: + await mainTokenGovernor.castVote(proposalIdForAddingSupportedToken, "1", {"from": STAKER_1}); + }); + + it('Wait 40 blocks and then check that the proposal status is: Succeeded', async() => { + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 40) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + + expect((await mainTokenGovernor.state(proposalIdForAddingSupportedToken)).toString()).to.equal("4"); + }); + + it('Queue the proposal', async() => { + + // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the + // description parameter, which we need to hash. + // + // A proposal can only be executed if the proposalId is the same as the one stored + // in the governer contract that has passed a vote. + // In the Governor.sol contract, the proposalId is created using all information used + // in to create the proposal: + // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); + + const result = await mainTokenGovernor.queue( + [mainTokenGovernor.address], + [0], + [encoded_function_add_supporting_token], + description_hash, + {"from": accounts[0]} + ); + }); + + + it('Create multiSig transaction to confirm proposal for adding supported tokens', async() => { + encodedConfirmation1 = _encodeConfirmation(proposalIdForAddingSupportedToken); + + const result = await multiSigWallet.submitTransaction( + mainTokenGovernor.address, + EMPTY_BYTES, + encodedConfirmation1, + 0, + {"from": accounts[0]} + ); + txIndex1 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + }) + + it('Should confirm transaction 1 from accounts[0], the first signer and accounts[1], the second signer', async() => { + await multiSigWallet.confirmTransaction(txIndex1, {"from": accounts[0]}); + await multiSigWallet.confirmTransaction(txIndex1, {"from": accounts[1]}); + }); + + + it('Execute the multiSig confirmation of proposal 1 and wait 40 blocks', async() => { + await multiSigWallet.executeTransaction(txIndex1, {"from": accounts[0]}); + + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 40) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + expect((await mainTokenGovernor.state(proposalIdForAddingSupportedToken)).toString()).to.equal("5"); + }); + + it('Execute the proposal', async() => { + + const result = await mainTokenGovernor.execute( + [mainTokenGovernor.address], + [0], + [encoded_function_add_supporting_token], + description_hash, + {"from": accounts[0]} + ); + }); + /// ------------- Relay Token -------/// + it('Propose to add relay Token to other address', async() => { + await streamReward1.transfer(mainTokenGovernor.address,web3.utils.toWei("10000","ether"),{from: accounts[0]}); + const eightHours = 28800 + await blockchain.increaseTime(eightHours) + encoded_function_relay = web3.eth.abi.encodeFunctionCall({ + name: 'relay', + type: 'function', + inputs: [{ + type: 'address', + name: 'target' + },{ + type: 'uint256', + name: 'value' + },{ + type: 'bytes', + name: 'data' + }] + }, [streamReward1.address, EMPTY_BYTES, _encodeTransferFunction(accounts[0])]); + // create a proposal in MainToken governor + result = await mainTokenGovernor.propose( + [mainTokenGovernor.address], + [0], + [encoded_function_relay], + PROPOSAL_DESCRIPTION, + {"from": STAKER_1} + ); + // retrieve the proposal id + proposalIdForRelayFunction = eventsHelper.getIndexedEventArgs(result, PROPOSAL_CREATED_EVENT)[0]; + }); + + it('Wait two blocks and then check that the proposal status is: Active', async() => { + + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 2) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + // Check that the proposal is open for voting + expect((await mainTokenGovernor.state(proposalIdForRelayFunction)).toString()).to.equal("1"); + }); + + it('Vote on the proposal', async() => { + + // enum VoteType { + // Against, + // For, + // Abstain + // } + // => 0 = Against, 1 = For, 2 = Abstain + + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 2) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + // Vote: + await mainTokenGovernor.castVote(proposalIdForRelayFunction, "1", {"from": STAKER_1}); + }); + + it('Wait 40 blocks and then check that the proposal status is: Succeeded', async() => { + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 40) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + + expect((await mainTokenGovernor.state(proposalIdForRelayFunction)).toString()).to.equal("4"); + }); + + it('Queue the proposal', async() => { + + // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the + // description parameter, which we need to hash. + // + // A proposal can only be executed if the proposalId is the same as the one stored + // in the governer contract that has passed a vote. + // In the Governor.sol contract, the proposalId is created using all information used + // in to create the proposal: + // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); + + const result = await mainTokenGovernor.queue( + [mainTokenGovernor.address], + [0], + [encoded_function_relay], + description_hash, + {"from": accounts[0]} + ); + }); + + + it('Create multiSig transaction to confirm proposal for adding supported tokens', async() => { + encodedConfirmation1 = _encodeConfirmation(proposalIdForRelayFunction); + + const result = await multiSigWallet.submitTransaction( + mainTokenGovernor.address, + EMPTY_BYTES, + encodedConfirmation1, + 0, + {"from": accounts[0]} + ); + txIndex1 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + }) + + it('Should confirm transaction 1 from accounts[0], the first signer and accounts[1], the second signer', async() => { + await multiSigWallet.confirmTransaction(txIndex1, {"from": accounts[0]}); + await multiSigWallet.confirmTransaction(txIndex1, {"from": accounts[1]}); + }); + + + it('Execute the multiSig confirmation of proposal 1 and wait 40 blocks', async() => { + await multiSigWallet.executeTransaction(txIndex1, {"from": accounts[0]}); + + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 40) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + expect((await mainTokenGovernor.state(proposalIdForRelayFunction)).toString()).to.equal("5"); + }); + + it('Execute the proposal', async() => { + + const result = await mainTokenGovernor.execute( + [mainTokenGovernor.address], + [0], + [encoded_function_relay], + description_hash, + {"from": accounts[0], + } + ); + }); }); }); From eabb2a0ed1eb86847b080d03ebaad5d7cdb0961b Mon Sep 17 00:00:00 2001 From: ssubik Date: Fri, 6 Jan 2023 19:06:00 +0545 Subject: [PATCH 23/77] fixed test --- scripts/tests/dao/full-flow-demo.test.js | 52 +++++++++++-------- .../dao/governance/proposal-flow.test.js | 2 +- 2 files changed, 32 insertions(+), 22 deletions(-) diff --git a/scripts/tests/dao/full-flow-demo.test.js b/scripts/tests/dao/full-flow-demo.test.js index 0de26cf..ee5cc69 100644 --- a/scripts/tests/dao/full-flow-demo.test.js +++ b/scripts/tests/dao/full-flow-demo.test.js @@ -97,6 +97,16 @@ const _calculateNumberOfVFTHM = (sumToDeposit, lockingPeriod, lockingWeight) =>{ return sumToDepositBN.mul(lockingPeriodBN).div(lockingWeightBN); } +const _createLockParamObject = ( + _amount, + _lockPeriod, + _account) => { + return { + amount: _amount, + lockPeriod: _lockPeriod, + account: _account + } +} const _calculateRemainingBalance = (depositAmount, beforeBalance) => { const depositAmountBN = new web3.utils.BN(depositAmount); @@ -137,24 +147,23 @@ const _encodeTransferFunction = (_account, t_to_stake) => { return toRet; } -const _encodeStakeFunction = (amounts, lockPeriods, accounts) => { +const _encodeStakeFunction = (_createLockParam) => { // encoded transfer function call for staking on behalf of someone else from treasury. - let toRet = web3.eth.abi.encodeFunctionCall({ - name: 'createLocksForCouncils', - type: 'function', + let toRet = web3.eth.abi.encodeFunctionCall({ + name:'createLocksForCouncils', + type:'function', inputs: [{ - type: 'uint256[]', - name: 'amounts' - },{ - type: 'uint256[]', - name: 'lockPeriods' - },{ - type: 'address[]', - name: 'accounts' - }] - }, [amounts, lockPeriods, accounts]); - - return toRet; + type: 'tuple[]', + name: 'CreateLockParams', + components: [ + {"type":"uint256", "name":"amount"}, + {"type":"uint256", "name":"lockPeriod"}, + {"type":"address", "name":"account"} + ] + } + ] + },[_createLockParam]) + return toRet } const _encodeStakeApproveFunction = (amount, spender) => { @@ -960,14 +969,15 @@ describe("DAO Demo", () => { {"from": accounts[0]} ); txIndex3 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; - const amounts = [amount,amount] - const lockPeriods = [oneYr,oneYr] - const commityAccounts = [comity_1,comity_2] - + const LockParamObjectForAllCouncils = [ + _createLockParamObject(amount,oneYr,comity_1), + _createLockParamObject(amount,oneYr,comity_2) + ] + let result2 = await multiSigWallet.submitTransaction( stakingService.address, EMPTY_BYTES, - _encodeStakeFunction(amounts, lockPeriods, commityAccounts), + _encodeStakeFunction(LockParamObjectForAllCouncils), 0, {"from": accounts[0]} ); diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 25e08f4..0016cd3 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -880,7 +880,7 @@ describe('Proposal flow', () => { }); - it('Create multiSig transaction to confirm proposal for adding supported tokens', async() => { + it('Create multiSig transaction to confirm proposal for relaying supported tokens', async() => { encodedConfirmation1 = _encodeConfirmation(proposalIdForRelayFunction); const result = await multiSigWallet.submitTransaction( From daa757804b549f91904ec18af91259f7fe434883 Mon Sep 17 00:00:00 2001 From: ssubik Date: Fri, 6 Jan 2023 22:20:25 +0545 Subject: [PATCH 24/77] npm run prettier --- contracts/common/Address.sol | 37 +++- contracts/common/SafeERC20.sol | 42 +++- contracts/common/cryptography/ECDSA.sol | 26 ++- contracts/common/cryptography/EIP712.sol | 6 +- contracts/common/math/FullMath.sol | 2 +- contracts/common/math/Math.sol | 6 +- contracts/common/proxy/StakingProxy.sol | 6 +- contracts/common/proxy/VaultProxy.sol | 6 +- .../common/proxy/transparent/ProxyAdmin.sol | 6 +- .../TransparentUpgradeableProxy.sol | 6 +- contracts/dao/governance/Governor.sol | 187 ++++++++++++------ .../dao/governance/MainTokenGovernor.sol | 17 +- .../dao/governance/TimelockController.sol | 31 +-- .../extensions/GovernorCountingSimple.sol | 11 +- .../extensions/GovernorSettings.sol | 8 +- .../extensions/GovernorTimelockControl.sol | 8 +- .../governance/extensions/GovernorVotes.sol | 8 +- .../dao/governance/extensions/IVotes.sol | 9 +- .../dao/governance/interfaces/IGovernor.sol | 35 +++- .../interfaces/ITimelockController.sol | 7 +- contracts/dao/staking/StakingStructs.sol | 10 +- .../staking/helpers/IStakingGetterHelper.sol | 11 +- .../staking/helpers/StakingGettersHelper.sol | 27 ++- .../dao/staking/interfaces/IStakingGetter.sol | 14 +- .../staking/interfaces/IStakingHandler.sol | 5 +- .../dao/staking/library/RewardsLibrary.sol | 6 +- .../dao/staking/library/StakingLibrary.sol | 13 +- .../staking/packages/RewardsCalculator.sol | 20 +- .../dao/staking/packages/RewardsInternals.sol | 6 +- .../dao/staking/packages/StakingGetters.sol | 10 +- .../dao/staking/packages/StakingHandler.sol | 55 +++--- .../dao/staking/packages/StakingInternals.sol | 52 ++++- .../dao/staking/vault/interfaces/IVault.sol | 20 +- .../staking/vault/packages/VaultPackage.sol | 53 ++--- contracts/dao/test/ERC20Rewards1.sol | 43 +++- contracts/dao/test/ERC20Rewards2.sol | 43 +++- .../dao/test/token-factory/ERC20Factory.sol | 12 +- .../interfaces/IERC20Factory.sol | 6 +- .../dao/test/token-timelock/TokenTimelock.sol | 6 +- .../token-timelock/TokenTimelockFactory.sol | 12 +- contracts/dao/tokens/ERC20/ERC20.sol | 36 +++- contracts/dao/tokens/ERC20/IERC20.sol | 6 +- .../tokens/ERC20/extensions/ERC20Permit.sol | 10 +- .../tokens/ERC20/extensions/ERC20Votes.sol | 21 +- .../tokens/ERC20/extensions/IERC20Permit.sol | 10 +- contracts/dao/tokens/IVMainToken.sol | 4 +- contracts/dao/tokens/MainToken.sol | 7 +- contracts/dao/tokens/VMainToken.sol | 17 +- contracts/dao/treasury/MultiSigWallet.sol | 124 +++++++----- .../treasury/interfaces/IMultiSigWallet.sol | 44 +++-- 50 files changed, 835 insertions(+), 332 deletions(-) diff --git a/contracts/common/Address.sol b/contracts/common/Address.sol index c05ea9d..e0fb54e 100644 --- a/contracts/common/Address.sol +++ b/contracts/common/Address.sol @@ -62,7 +62,11 @@ library Address { * * _Available since v3.1._ */ - function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { + function functionCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } @@ -77,7 +81,11 @@ library Address { * * _Available since v3.1._ */ - function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { + function functionCallWithValue( + address target, + bytes memory data, + uint256 value + ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } @@ -87,7 +95,12 @@ library Address { * * _Available since v3.1._ */ - function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { + function functionCallWithValue( + address target, + bytes memory data, + uint256 value, + string memory errorMessage + ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); @@ -111,7 +124,11 @@ library Address { * * _Available since v3.4._ */ - function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { + function functionDelegateCall( + address target, + bytes memory data, + string memory errorMessage + ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); @@ -168,7 +185,11 @@ library Address { * * _Available since v3.3._ */ - function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { + function functionStaticCall( + address target, + bytes memory data, + string memory errorMessage + ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); @@ -189,7 +210,11 @@ library Address { * * _Available since v4.3._ */ - function verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) internal pure returns (bytes memory) { + function verifyCallResult( + bool success, + bytes memory returndata, + string memory errorMessage + ) internal pure returns (bytes memory) { if (success) { return returndata; } else { diff --git a/contracts/common/SafeERC20.sol b/contracts/common/SafeERC20.sol index 2946d92..116dce6 100644 --- a/contracts/common/SafeERC20.sol +++ b/contracts/common/SafeERC20.sol @@ -19,11 +19,20 @@ import "./Address.sol"; library SafeERC20 { using Address for address; - function safeTransfer(IERC20 token, address to, uint256 value) internal { + function safeTransfer( + IERC20 token, + address to, + uint256 value + ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } - function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { + function safeTransferFrom( + IERC20 token, + address from, + address to, + uint256 value + ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } @@ -34,7 +43,11 @@ library SafeERC20 { * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ - function safeApprove(IERC20 token, address spender, uint256 value) internal { + function safeApprove( + IERC20 token, + address spender, + uint256 value + ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' @@ -42,12 +55,20 @@ library SafeERC20 { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } - function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { + function safeIncreaseAllowance( + IERC20 token, + address spender, + uint256 value + ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } - function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { + function safeDecreaseAllowance( + IERC20 token, + address spender, + uint256 value + ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); @@ -56,7 +77,16 @@ library SafeERC20 { } } - function safePermit(IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) internal { + function safePermit( + IERC20Permit token, + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); diff --git a/contracts/common/cryptography/ECDSA.sol b/contracts/common/cryptography/ECDSA.sol index 460e39d..5b490a3 100644 --- a/contracts/common/cryptography/ECDSA.sol +++ b/contracts/common/cryptography/ECDSA.sol @@ -101,7 +101,11 @@ library ECDSA { * * _Available since v4.3._ */ - function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) { + function tryRecover( + bytes32 hash, + bytes32 r, + bytes32 vs + ) internal pure returns (address, RecoverError) { bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff); uint8 v = uint8((uint256(vs) >> 255) + 27); return tryRecover(hash, v, r, s); @@ -112,7 +116,11 @@ library ECDSA { * * _Available since v4.2._ */ - function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) { + function recover( + bytes32 hash, + bytes32 r, + bytes32 vs + ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, r, vs); _throwError(error); return recovered; @@ -124,7 +132,12 @@ library ECDSA { * * _Available since v4.3._ */ - function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) { + function tryRecover( + bytes32 hash, + uint8 v, + bytes32 r, + bytes32 s + ) internal pure returns (address, RecoverError) { // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most @@ -154,7 +167,12 @@ library ECDSA { * @dev Overload of {ECDSA-recover} that receives the `v`, * `r` and `s` signature fields separately. */ - function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) { + function recover( + bytes32 hash, + uint8 v, + bytes32 r, + bytes32 s + ) internal pure returns (address) { (address recovered, RecoverError error) = tryRecover(hash, v, r, s); _throwError(error); return recovered; diff --git a/contracts/common/cryptography/EIP712.sol b/contracts/common/cryptography/EIP712.sol index 56c8d7e..cc8f0dd 100644 --- a/contracts/common/cryptography/EIP712.sol +++ b/contracts/common/cryptography/EIP712.sol @@ -101,7 +101,11 @@ abstract contract EIP712 { return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash); } - function _buildDomainSeparator(bytes32 typeHash, bytes32 nameHash, bytes32 versionHash) private view returns (bytes32) { + function _buildDomainSeparator( + bytes32 typeHash, + bytes32 nameHash, + bytes32 versionHash + ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, getChainID(), address(this))); } } diff --git a/contracts/common/math/FullMath.sol b/contracts/common/math/FullMath.sol index ff691fd..e357426 100644 --- a/contracts/common/math/FullMath.sol +++ b/contracts/common/math/FullMath.sol @@ -125,4 +125,4 @@ library FullMath { } } } -} \ No newline at end of file +} diff --git a/contracts/common/math/Math.sol b/contracts/common/math/Math.sol index 2350f88..2bb4231 100644 --- a/contracts/common/math/Math.sol +++ b/contracts/common/math/Math.sol @@ -10,14 +10,14 @@ library Math { /** * @dev Returns the largest of two numbers. */ - function max(uint a, uint b) internal pure returns (uint) { + function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ - function min(uint a, uint b) internal pure returns (uint) { + function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } @@ -25,7 +25,7 @@ library Math { * @dev Returns the average of two numbers. The result is rounded towards * zero. */ - function average(uint a, uint b) internal pure returns (uint) { + function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow, so we distribute return (a / 2) + (b / 2) + (((a % 2) + (b % 2)) / 2); } diff --git a/contracts/common/proxy/StakingProxy.sol b/contracts/common/proxy/StakingProxy.sol index 9631043..141daf5 100644 --- a/contracts/common/proxy/StakingProxy.sol +++ b/contracts/common/proxy/StakingProxy.sol @@ -5,5 +5,9 @@ pragma solidity ^0.8.0; import "./transparent/TransparentUpgradeableProxy.sol"; contract StakingProxy is TransparentUpgradeableProxy { - constructor(address _logic, address admin_, bytes memory _data) payable TransparentUpgradeableProxy(_logic, admin_, _data) {} + constructor( + address _logic, + address admin_, + bytes memory _data + ) payable TransparentUpgradeableProxy(_logic, admin_, _data) {} } diff --git a/contracts/common/proxy/VaultProxy.sol b/contracts/common/proxy/VaultProxy.sol index 62c7bd8..950d836 100644 --- a/contracts/common/proxy/VaultProxy.sol +++ b/contracts/common/proxy/VaultProxy.sol @@ -5,5 +5,9 @@ pragma solidity ^0.8.0; import "./transparent/TransparentUpgradeableProxy.sol"; contract VaultProxy is TransparentUpgradeableProxy { - constructor(address _logic, address admin_, bytes memory _data) payable TransparentUpgradeableProxy(_logic, admin_, _data) {} + constructor( + address _logic, + address admin_, + bytes memory _data + ) payable TransparentUpgradeableProxy(_logic, admin_, _data) {} } diff --git a/contracts/common/proxy/transparent/ProxyAdmin.sol b/contracts/common/proxy/transparent/ProxyAdmin.sol index 7870758..2908d87 100644 --- a/contracts/common/proxy/transparent/ProxyAdmin.sol +++ b/contracts/common/proxy/transparent/ProxyAdmin.sol @@ -71,7 +71,11 @@ contract ProxyAdmin is Ownable { * * - This contract must be the admin of `proxy`. */ - function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner { + function upgradeAndCall( + TransparentUpgradeableProxy proxy, + address implementation, + bytes memory data + ) public payable virtual onlyOwner { proxy.upgradeToAndCall{ value: msg.value }(implementation, data); } } diff --git a/contracts/common/proxy/transparent/TransparentUpgradeableProxy.sol b/contracts/common/proxy/transparent/TransparentUpgradeableProxy.sol index 9b04d91..5a9dc76 100644 --- a/contracts/common/proxy/transparent/TransparentUpgradeableProxy.sol +++ b/contracts/common/proxy/transparent/TransparentUpgradeableProxy.sol @@ -31,7 +31,11 @@ contract TransparentUpgradeableProxy is ERC1967Proxy { * @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and * optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}. */ - constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) { + constructor( + address _logic, + address admin_, + bytes memory _data + ) payable ERC1967Proxy(_logic, _data) { _changeAdmin(admin_); } diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 18ea22f..1f27dd0 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -22,9 +22,9 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { using Strings for *; using Timers for Timers.BlockNumber; - event ConfirmProposal(address indexed signer, uint indexed proposalId); - event RevokeConfirmation(address indexed signer, uint indexed proposalId); - event ExecuteProposal(address indexed signer, uint indexed proposalId); + event ConfirmProposal(address indexed signer, uint256 indexed proposalId); + event RevokeConfirmation(address indexed signer, uint256 indexed proposalId); + event ExecuteProposal(address indexed signer, uint256 indexed proposalId); event MultiSigUpdated(address newMultiSig, address oldMultiSig); event MaxTargetUpdated(uint256 newMaxTargets, uint256 oldMaxTargets); event ProposalTimeDelayUpdated(uint256 newProposalTimeDelay, uint256 oldProposalTimeDelay); @@ -35,13 +35,13 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { uint256 public proposalTimeDelay; string private _name; uint256[] private proposalIds; - + address private multiSig; mapping(uint256 => ProposalCore) internal _proposals; mapping(uint256 => string) internal _descriptions; - mapping(uint => bool) public isConfirmed; - mapping(address => uint) public nextAcceptableProposalTimestamp; + mapping(uint256 => bool) public isConfirmed; + mapping(address => uint256) public nextAcceptableProposalTimestamp; DoubleEndedQueue.Bytes32Deque private _governanceCall; @@ -60,25 +60,25 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { _; } - modifier notExecuted(uint _proposalId) { + modifier notExecuted(uint256 _proposalId) { require(!_proposals[_proposalId].executed, "proposal already executed"); _; } - modifier notConfirmed(uint _proposalId) { + modifier notConfirmed(uint256 _proposalId) { require(!isConfirmed[_proposalId], "proposal already confirmed"); _; } constructor( - string memory name_, - address multiSig_, + string memory name_, + address multiSig_, uint256 maxTargets_, - uint256 proposalTimeDelay_) EIP712(name_, version()) - { - require(multiSig_ != address(0),"multiSig address cant be zero address"); - require(maxTargets_ != 0,"maxTarget cant be zero"); - require(proposalTimeDelay_ != 0,"proposalTimeDelay cant be zero"); + uint256 proposalTimeDelay_ + ) EIP712(name_, version()) { + require(multiSig_ != address(0), "multiSig address cant be zero address"); + require(maxTargets_ != 0, "maxTarget cant be zero"); + require(proposalTimeDelay_ != 0, "proposalTimeDelay cant be zero"); _name = name_; multiSig = multiSig_; maxTargets = maxTargets_; @@ -94,27 +94,26 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash - ) public whenNotPaused payable virtual override returns (uint256) { + ) public payable virtual override whenNotPaused returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); requireConfirmed(proposalId); ProposalState status = state(proposalId); require(status == ProposalState.Queued, "Governor: proposal not successful"); uint256 totalValue = 0; - for (uint256 i = 0;i < values.length; i++){ + for (uint256 i = 0; i < values.length; i++) { totalValue += values[i]; } require(msg.value >= totalValue, "execute: msg.value not sufficient"); _proposals[proposalId].executed = true; - emit ProposalExecuted(proposalId); _beforeExecute(proposalId, targets, values, calldatas, descriptionHash); _execute(proposalId, targets, values, calldatas, descriptionHash); _afterExecute(proposalId, targets, values, calldatas, descriptionHash); - if(msg.value > totalValue){ - (bool sent, ) = msg.sender.call{value: (msg.value - totalValue)}(""); + if (msg.value > totalValue) { + (bool sent, ) = msg.sender.call{ value: (msg.value - totalValue) }(""); require(sent, "Failed to send ether"); } return proposalId; @@ -125,7 +124,11 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return _castVote(proposalId, voter, support, ""); } - function castVoteWithReason(uint256 proposalId, uint8 support, string memory reason) public virtual override returns (uint256) { + function castVoteWithReason( + uint256 proposalId, + uint8 support, + string memory reason + ) public virtual override returns (uint256) { address voter = _msgSender(); return _castVote(proposalId, voter, support, reason); } @@ -140,7 +143,13 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return _castVote(proposalId, voter, support, reason, params); } - function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) public virtual override returns (uint256) { + function castVoteBySig( + uint256 proposalId, + uint8 support, + uint8 v, + bytes32 r, + bytes32 s + ) public virtual override returns (uint256) { address voter = ECDSA.recover(_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), v, r, s); return _castVote(proposalId, voter, support, ""); } @@ -169,13 +178,11 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { uint256[] memory values, bytes[] memory calldatas, string memory description - ) public whenNotPaused virtual override returns (uint256) { - + ) public virtual override whenNotPaused returns (uint256) { require(getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold"); - - require(block.timestamp > nextAcceptableProposalTimestamp[msg.sender], - "Governor: Can only submit one proposal for a certain interval"); - + + require(block.timestamp > nextAcceptableProposalTimestamp[msg.sender], "Governor: Can only submit one proposal for a certain interval"); + nextAcceptableProposalTimestamp[msg.sender] = block.timestamp + proposalTimeDelay; uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); @@ -183,7 +190,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { require(targets.length == values.length, "Governor: invalid proposal length"); require(targets.length == calldatas.length, "Governor: invalid proposal length"); require(targets.length > 0, "Governor: empty proposal"); - require(targets.length <= maxTargets,"Governor: max target length"); + require(targets.length <= maxTargets, "Governor: max target length"); ProposalCore storage proposal = _proposals[proposalId]; require(proposal.voteStart.isUnset(), "Governor: proposal already exists"); @@ -202,14 +209,14 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return proposalId; } - function confirmProposal(uint _proposalId) public onlyMultiSig notExecuted(_proposalId) notConfirmed(_proposalId) { + function confirmProposal(uint256 _proposalId) public onlyMultiSig notExecuted(_proposalId) notConfirmed(_proposalId) { isConfirmed[_proposalId] = true; ProposalState status = state(_proposalId); require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); emit ConfirmProposal(msg.sender, _proposalId); } - function revokeConfirmation(uint _proposalId) public onlyMultiSig notExecuted(_proposalId) { + function revokeConfirmation(uint256 _proposalId) public onlyMultiSig notExecuted(_proposalId) { requireConfirmed(_proposalId); isConfirmed[_proposalId] = false; @@ -223,28 +230,37 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { multiSig = newMultiSig; } - function updateMaxTargets(uint256 newMaxTargets) public onlyMultiSig{ - require(newMaxTargets != 0,"updateMaxTargets: newMaxTargets cant be zero"); + function updateMaxTargets(uint256 newMaxTargets) public onlyMultiSig { + require(newMaxTargets != 0, "updateMaxTargets: newMaxTargets cant be zero"); emit MaxTargetUpdated(newMaxTargets, maxTargets); maxTargets = newMaxTargets; } function updateProposalTimeDelay(uint256 newProposalTimeDelay) public onlyMultiSig { - require(newProposalTimeDelay != 0,"updateProposalTimeDelay: newProposalTimeDelay cant be zero"); + require(newProposalTimeDelay != 0, "updateProposalTimeDelay: newProposalTimeDelay cant be zero"); emit ProposalTimeDelayUpdated(newProposalTimeDelay, proposalTimeDelay); proposalTimeDelay = newProposalTimeDelay; } - function emergencyStop() public onlyMultiSig{ + function emergencyStop() public onlyMultiSig { _pause(); } - function unpause() public onlyMultiSig{ + function unpause() public onlyMultiSig { _unpause(); } - - function getProposals(uint _numIndexes) public view override returns (string[] memory, string[] memory, string[] memory) { - uint len = proposalIds.length; + + function getProposals(uint256 _numIndexes) + public + view + override + returns ( + string[] memory, + string[] memory, + string[] memory + ) + { + uint256 len = proposalIds.length; if (len == 0) { string[] memory a; @@ -258,22 +274,29 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return _getProposals1(_numIndexes); } - - function _getProposals1(uint _numIndexes) internal view returns (string[] memory, string[] memory, string[] memory) { + function _getProposals1(uint256 _numIndexes) + internal + view + returns ( + string[] memory, + string[] memory, + string[] memory + ) + { string[] memory _statusses = new string[](_numIndexes); string[] memory _descriptionsArray = new string[](_numIndexes); string[] memory _proposalIds = new string[](_numIndexes); - uint counter = proposalIds.length; + uint256 counter = proposalIds.length; - uint indexCounter = _numIndexes - 1; + uint256 indexCounter = _numIndexes - 1; if (_numIndexes >= counter) { indexCounter = counter - 1; } while (indexCounter >= 0) { - uint _currentPropId = proposalIds[counter - 1]; + uint256 _currentPropId = proposalIds[counter - 1]; _proposalIds[indexCounter] = string(_currentPropId.toString()); _descriptionsArray[indexCounter] = _descriptions[_currentPropId]; _statusses[indexCounter] = (uint8(state(_currentPropId))).toString(); @@ -292,11 +315,11 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return (_proposalIds, _descriptionsArray, _statusses); } - function getProposalIds() public view override returns (uint[] memory) { + function getProposalIds() public view override returns (uint256[] memory) { return proposalIds; } - function getDescription(uint _proposalId) public view override returns (string memory) { + function getDescription(uint256 _proposalId) public view override returns (string memory) { return _descriptions[_proposalId]; } @@ -304,7 +327,11 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return _getVotes(account, blockNumber, _defaultParams()); } - function getVotesWithParams(address account, uint256 blockNumber, bytes memory params) public view virtual override returns (uint256) { + function getVotesWithParams( + address account, + uint256 blockNumber, + bytes memory params + ) public view virtual override returns (uint256) { return _getVotes(account, blockNumber, params); } @@ -382,10 +409,16 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return uint256(keccak256(abi.encode(targets, values, calldatas, descriptionHash))); } - function _countVote(uint256 proposalId, address account, uint8 support, uint256 weight, bytes memory params) internal virtual; + function _countVote( + uint256 proposalId, + address account, + uint8 support, + uint256 weight, + bytes memory params + ) internal virtual; function _execute( - uint256 /*proposalId*/ , + uint256, /*proposalId*/ address[] memory targets, uint256[] memory values, bytes[] memory calldatas, @@ -398,11 +431,10 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { } } - function _beforeExecute( - uint256 /* proposalId */, + uint256, /* proposalId */ address[] memory targets, - uint256[] memory /* values */, + uint256[] memory, /* values */ bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { @@ -416,10 +448,10 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { } function _afterExecute( - uint256 /* proposalId */, - address[] memory /* targets */, - uint256[] memory /* values */, - bytes[] memory /* calldatas */, + uint256, /* proposalId */ + address[] memory, /* targets */ + uint256[] memory, /* values */ + bytes[] memory, /* calldatas */ bytes32 /*descriptionHash*/ ) internal virtual { if (_executor() != address(this)) { @@ -449,7 +481,12 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return proposalId; } - function _castVote(uint256 proposalId, address account, uint8 support, string memory reason) internal virtual returns (uint256) { + function _castVote( + uint256 proposalId, + address account, + uint8 support, + string memory reason + ) internal virtual returns (uint256) { return _castVote(proposalId, account, support, reason, _defaultParams()); } @@ -475,14 +512,22 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return weight; } - function _getProposalsAll(uint len) internal view returns (string[] memory, string[] memory, string[] memory) { + function _getProposalsAll(uint256 len) + internal + view + returns ( + string[] memory, + string[] memory, + string[] memory + ) + { string[] memory _statusses = new string[](len); string[] memory _descriptionsArray = new string[](len); string[] memory _proposalIds = new string[](len); - uint i = len - 1; + uint256 i = len - 1; while (i >= 0) { - uint _proposalId = proposalIds[i]; + uint256 _proposalId = proposalIds[i]; _proposalIds[i] = _proposalId.toString(); _descriptionsArray[i] = _descriptions[_proposalId]; _statusses[i] = (uint8(state(_proposalId))).toString(); @@ -496,16 +541,24 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return (_proposalIds, _descriptionsArray, _statusses); } - function _getProposals(uint _numIndexes, uint len) internal view returns (string[] memory, string[] memory, string[] memory) { + function _getProposals(uint256 _numIndexes, uint256 len) + internal + view + returns ( + string[] memory, + string[] memory, + string[] memory + ) + { string[] memory _statusses = new string[](_numIndexes); string[] memory _descriptionsArray = new string[](_numIndexes); string[] memory _proposalIds = new string[](_numIndexes); // uint _lb = len - _numIndexes; - uint i = _numIndexes; + uint256 i = _numIndexes; while (i > 0) { - uint _proposalId = proposalIds[len - 1 - i]; + uint256 _proposalId = proposalIds[len - 1 - i]; _proposalIds[i - 1] = _proposalId.toString(); _descriptionsArray[i - 1] = _descriptions[_proposalId]; _statusses[i - 1] = (uint8(state(_proposalId))).toString(); @@ -519,7 +572,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { return (_proposalIds, _descriptionsArray, _statusses); } - function requireConfirmed(uint _proposalId) internal view { + function requireConfirmed(uint256 _proposalId) internal view { require(isConfirmed[_proposalId], "proposal not confirmed"); } @@ -531,7 +584,11 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { function _voteSucceeded(uint256 proposalId) internal view virtual returns (bool); - function _getVotes(address account, uint256 blockNumber, bytes memory params) internal view virtual returns (uint256); + function _getVotes( + address account, + uint256 blockNumber, + bytes memory params + ) internal view virtual returns (uint256); function _defaultParams() internal view virtual returns (bytes memory) { return ""; diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index f182f19..0bd340b 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -19,10 +19,11 @@ contract MainTokenGovernor is GovernorVotes, GovernorVotesQuorumFraction, GovernorTimelockControl -{ +{ using SafeERC20 for IERC20; mapping(address => bool) public isSupportedToken; uint256 public constant EIGHT_HOURS = 28800; + constructor( IVotes _token, TimelockController _timelock, @@ -31,7 +32,7 @@ contract MainTokenGovernor is uint256 _votingPeriod, uint256 _initialProposalThreshold ) - Governor("MainTokenGovernor", _multiSig,20,EIGHT_HOURS) + Governor("MainTokenGovernor", _multiSig, 20, EIGHT_HOURS) GovernorSettings(_initialVotingDelay, _votingPeriod, _initialProposalThreshold) GovernorVotes(_token) GovernorVotesQuorumFraction(4) @@ -52,7 +53,7 @@ contract MainTokenGovernor is uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash - ) public onlyMultiSig override returns (uint256) { + ) public override onlyMultiSig returns (uint256) { return _cancel(targets, values, calldatas, descriptionHash); } @@ -96,9 +97,13 @@ contract MainTokenGovernor is * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. * Note that if the executor is simply the governor itself, use of `relay` is redundant. */ - function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance { - require(isSupportedToken[target],"relay: token not supported"); - (bool success, bytes memory returndata) = target.call{value: value}(data); + function relay( + address target, + uint256 value, + bytes calldata data + ) external payable virtual onlyGovernance { + require(isSupportedToken[target], "relay: token not supported"); + (bool success, bytes memory returndata) = target.call{ value: value }(data); Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); } diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index f84ec45..2614040 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -46,9 +46,14 @@ contract TimelockController is AccessControl, Initializable, ITimelockController _; } - function initialize(uint256 minDelay, address admin, address[] memory proposers, address[] memory executors) public override initializer { - require(minDelay!=0,"minDelay should be greater than zero"); - require(admin!=address(0),"admin should not be zero address"); + function initialize( + uint256 minDelay, + address admin, + address[] memory proposers, + address[] memory executors + ) public override initializer { + require(minDelay != 0, "minDelay should be greater than zero"); + require(admin != address(0), "admin should not be zero address"); _setRoleAdmin(TIMELOCK_ADMIN_ROLE, TIMELOCK_ADMIN_ROLE); _setRoleAdmin(PROPOSER_ROLE, TIMELOCK_ADMIN_ROLE); _setRoleAdmin(EXECUTOR_ROLE, TIMELOCK_ADMIN_ROLE); @@ -60,13 +65,13 @@ contract TimelockController is AccessControl, Initializable, ITimelockController _grantRole(DEFAULT_ADMIN_ROLE, admin); for (uint256 i = 0; i < proposers.length; ++i) { - require(proposers[i] !=address(0),"proposer should not be zero address"); + require(proposers[i] != address(0), "proposer should not be zero address"); _setupRole(PROPOSER_ROLE, proposers[i]); _setupRole(CANCELLER_ROLE, proposers[i]); } for (uint256 i = 0; i < executors.length; ++i) { - require(executors[i] !=address(0),"executor should not be zero address"); + require(executors[i] != address(0), "executor should not be zero address"); _setupRole(EXECUTOR_ROLE, executors[i]); } @@ -113,7 +118,7 @@ contract TimelockController is AccessControl, Initializable, ITimelockController emit Cancelled(id); } - + function execute( address target, uint256 value, @@ -122,13 +127,13 @@ contract TimelockController is AccessControl, Initializable, ITimelockController bytes32 salt ) public payable virtual onlyRoleOrOpenRole(EXECUTOR_ROLE) { bytes32 id = hashOperation(target, value, payload, predecessor, salt); - require(msg.value >= value,"execute: msg.value insufficient sent"); + require(msg.value >= value, "execute: msg.value insufficient sent"); _beforeCall(id, predecessor); _execute(target, value, payload); emit CallExecuted(id, 0, target, value, payload); _afterCall(id); - if(msg.value > value){ - (bool sent, ) = msg.sender.call{value: (msg.value - value)}(""); + if (msg.value > value) { + (bool sent, ) = msg.sender.call{ value: (msg.value - value) }(""); require(sent, "Failed to send ether"); } } @@ -158,7 +163,7 @@ contract TimelockController is AccessControl, Initializable, ITimelockController function updateDelay(uint256 newDelay) public virtual { require(msg.sender == address(this), "TimelockController: caller must be timelock"); - require(newDelay>0,"new delay should be greater than zero"); + require(newDelay > 0, "new delay should be greater than zero"); emit MinDelayChange(_minDelay, newDelay); _minDelay = newDelay; } @@ -212,7 +217,11 @@ contract TimelockController is AccessControl, Initializable, ITimelockController return keccak256(abi.encode(targets, values, payloads, predecessor, salt)); } - function _execute(address target, uint256 value, bytes memory data) internal virtual { + function _execute( + address target, + uint256 value, + bytes memory data + ) internal virtual { (bool success, ) = target.call{ value: value }(data); require(success, "TimelockController: underlying transaction reverted"); } diff --git a/contracts/dao/governance/extensions/GovernorCountingSimple.sol b/contracts/dao/governance/extensions/GovernorCountingSimple.sol index 6be1844..05cd0c1 100644 --- a/contracts/dao/governance/extensions/GovernorCountingSimple.sol +++ b/contracts/dao/governance/extensions/GovernorCountingSimple.sol @@ -26,7 +26,16 @@ abstract contract GovernorCountingSimple is Governor { return _proposalVotes[proposalId].hasVoted[account]; } - function proposalVotes(uint256 proposalId) public view virtual returns (uint256 againstVotes, uint256 forVotes, uint256 abstainVotes) { + function proposalVotes(uint256 proposalId) + public + view + virtual + returns ( + uint256 againstVotes, + uint256 forVotes, + uint256 abstainVotes + ) + { ProposalVote storage proposalvote = _proposalVotes[proposalId]; return (proposalvote.againstVotes, proposalvote.forVotes, proposalvote.abstainVotes); } diff --git a/contracts/dao/governance/extensions/GovernorSettings.sol b/contracts/dao/governance/extensions/GovernorSettings.sol index ce5f628..abb3eea 100644 --- a/contracts/dao/governance/extensions/GovernorSettings.sol +++ b/contracts/dao/governance/extensions/GovernorSettings.sol @@ -15,7 +15,11 @@ abstract contract GovernorSettings is Governor { event VotingPeriodSet(uint256 oldVotingPeriod, uint256 newVotingPeriod); event ProposalThresholdSet(uint256 oldProposalThreshold, uint256 newProposalThreshold); - constructor(uint256 initialVotingDelay, uint256 initialVotingPeriod, uint256 initialProposalThreshold) { + constructor( + uint256 initialVotingDelay, + uint256 initialVotingPeriod, + uint256 initialProposalThreshold + ) { _setVotingDelay(initialVotingDelay); _setVotingPeriod(initialVotingPeriod); _setProposalThreshold(initialProposalThreshold); @@ -58,7 +62,7 @@ abstract contract GovernorSettings is Governor { function _setProposalThreshold(uint256 newProposalThreshold) internal virtual { emit ProposalThresholdSet(_proposalThreshold, newProposalThreshold); - require(newProposalThreshold > 0,"_setProposalThreshold: Threshold for proposal cant be zero"); + require(newProposalThreshold > 0, "_setProposalThreshold: Threshold for proposal cant be zero"); _proposalThreshold = newProposalThreshold; } } diff --git a/contracts/dao/governance/extensions/GovernorTimelockControl.sol b/contracts/dao/governance/extensions/GovernorTimelockControl.sol index be3a231..582631f 100644 --- a/contracts/dao/governance/extensions/GovernorTimelockControl.sol +++ b/contracts/dao/governance/extensions/GovernorTimelockControl.sol @@ -15,7 +15,7 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { event TimelockChange(address oldTimelock, address newTimelock); constructor(TimelockController timelockAddress) { - require(address(timelockAddress) != address(0),"timelockAddress cant be zero address"); + require(address(timelockAddress) != address(0), "timelockAddress cant be zero address"); _updateTimelock(timelockAddress); } @@ -50,7 +50,7 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { function state(uint256 proposalId) public view virtual override(IGovernor, Governor) returns (ProposalState) { ProposalState status = super.state(proposalId); - + if (status != ProposalState.Succeeded) { return status; } @@ -77,13 +77,13 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { } function _execute( - uint256 proposalId, + uint256 proposalId, address[] memory targets, uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash ) internal virtual override { - require(!isProposalExecuted[proposalId],"_execute: proposal already executed"); + require(!isProposalExecuted[proposalId], "_execute: proposal already executed"); _timelock.executeBatch{ value: msg.value }(targets, values, calldatas, 0, descriptionHash); isProposalExecuted[proposalId] = true; } diff --git a/contracts/dao/governance/extensions/GovernorVotes.sol b/contracts/dao/governance/extensions/GovernorVotes.sol index 94bd019..b6b16ed 100644 --- a/contracts/dao/governance/extensions/GovernorVotes.sol +++ b/contracts/dao/governance/extensions/GovernorVotes.sol @@ -11,11 +11,15 @@ abstract contract GovernorVotes is Governor { IVotes public immutable token; constructor(IVotes tokenAddress) { - require(address(tokenAddress) != address(0),"tokenAddress cant be zero address"); + require(address(tokenAddress) != address(0), "tokenAddress cant be zero address"); token = tokenAddress; } - function _getVotes(address account, uint256 blockNumber, bytes memory /*params*/) internal view virtual override returns (uint256) { + function _getVotes( + address account, + uint256 blockNumber, + bytes memory /*params*/ + ) internal view virtual override returns (uint256) { return token.getPastVotes(account, blockNumber); } } diff --git a/contracts/dao/governance/extensions/IVotes.sol b/contracts/dao/governance/extensions/IVotes.sol index de22d4a..76c3c78 100644 --- a/contracts/dao/governance/extensions/IVotes.sol +++ b/contracts/dao/governance/extensions/IVotes.sol @@ -10,7 +10,14 @@ interface IVotes { function delegate(address delegatee) external; - function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) external; + function delegateBySig( + address delegatee, + uint256 nonce, + uint256 expiry, + uint8 v, + bytes32 r, + bytes32 s + ) external; function getVotes(address account) external view returns (uint256); diff --git a/contracts/dao/governance/interfaces/IGovernor.sol b/contracts/dao/governance/interfaces/IGovernor.sol index 00c323e..1299790 100644 --- a/contracts/dao/governance/interfaces/IGovernor.sol +++ b/contracts/dao/governance/interfaces/IGovernor.sol @@ -51,6 +51,7 @@ abstract contract IGovernor is IERC165 { bytes[] memory calldatas, bytes32 descriptionHash ) public virtual returns (uint256); + function execute( address[] memory targets, uint256[] memory values, @@ -60,7 +61,11 @@ abstract contract IGovernor is IERC165 { function castVote(uint256 proposalId, uint8 support) public virtual returns (uint256 balance); - function castVoteWithReason(uint256 proposalId, uint8 support, string memory reason) public virtual returns (uint256 balance); + function castVoteWithReason( + uint256 proposalId, + uint8 support, + string memory reason + ) public virtual returns (uint256 balance); function castVoteWithReasonAndParams( uint256 proposalId, @@ -69,7 +74,13 @@ abstract contract IGovernor is IERC165 { bytes memory params ) public virtual returns (uint256 balance); - function castVoteBySig(uint256 proposalId, uint8 support, uint8 v, bytes32 r, bytes32 s) public virtual returns (uint256 balance); + function castVoteBySig( + uint256 proposalId, + uint8 support, + uint8 v, + bytes32 r, + bytes32 s + ) public virtual returns (uint256 balance); function castVoteWithReasonAndParamsBySig( uint256 proposalId, @@ -81,11 +92,19 @@ abstract contract IGovernor is IERC165 { bytes32 s ) public virtual returns (uint256 balance); - function getProposals(uint _numIndexes) public view virtual returns (string[] memory, string[] memory, string[] memory); + function getProposals(uint256 _numIndexes) + public + view + virtual + returns ( + string[] memory, + string[] memory, + string[] memory + ); - function getDescription(uint _proposalId) public view virtual returns (string memory); + function getDescription(uint256 _proposalId) public view virtual returns (string memory); - function getProposalIds() public view virtual returns (uint[] memory); + function getProposalIds() public view virtual returns (uint256[] memory); function name() public view virtual returns (string memory); @@ -105,7 +124,11 @@ abstract contract IGovernor is IERC165 { function getVotes(address account, uint256 blockNumber) public view virtual returns (uint256); - function getVotesWithParams(address account, uint256 blockNumber, bytes memory params) public view virtual returns (uint256); + function getVotesWithParams( + address account, + uint256 blockNumber, + bytes memory params + ) public view virtual returns (uint256); function hasVoted(uint256 proposalId, address account) public view virtual returns (bool); diff --git a/contracts/dao/governance/interfaces/ITimelockController.sol b/contracts/dao/governance/interfaces/ITimelockController.sol index 566c44b..c6f9429 100644 --- a/contracts/dao/governance/interfaces/ITimelockController.sol +++ b/contracts/dao/governance/interfaces/ITimelockController.sol @@ -4,5 +4,10 @@ pragma solidity 0.8.13; interface ITimelockController { - function initialize(uint256 minDelay, address admin, address[] calldata proposers, address[] calldata executors) external; + function initialize( + uint256 minDelay, + address admin, + address[] calldata proposers, + address[] calldata executors + ) external; } diff --git a/contracts/dao/staking/StakingStructs.sol b/contracts/dao/staking/StakingStructs.sol index e0fa371..5578e26 100644 --- a/contracts/dao/staking/StakingStructs.sol +++ b/contracts/dao/staking/StakingStructs.sol @@ -65,8 +65,8 @@ struct Stream { Schedule schedule; } -struct CreateLockParams{ - uint256 amount; - uint256 lockPeriod; - address account; - } +struct CreateLockParams { + uint256 amount; + uint256 lockPeriod; + address account; +} diff --git a/contracts/dao/staking/helpers/IStakingGetterHelper.sol b/contracts/dao/staking/helpers/IStakingGetterHelper.sol index bab7bba..dce197e 100644 --- a/contracts/dao/staking/helpers/IStakingGetterHelper.sol +++ b/contracts/dao/staking/helpers/IStakingGetterHelper.sol @@ -11,7 +11,16 @@ import "../../../common/security/IAdminPausable.sol"; interface IStakingGetterHelper { function getLockInfo(address account, uint256 lockId) external view returns (LockedBalance memory); - function getLock(address account, uint lockId) external view returns (uint128, uint128, uint128, uint64, address); + function getLock(address account, uint256 lockId) + external + view + returns ( + uint128, + uint128, + uint128, + uint64, + address + ); function getUserTotalDeposit(address account) external view returns (uint256); diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index dc96980..8e230c2 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -30,7 +30,18 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { return locks.length; } - function getLock(address account, uint lockId) public view override returns (uint128, uint128, uint128, uint64, address) { + function getLock(address account, uint256 lockId) + public + view + override + returns ( + uint128, + uint128, + uint128, + uint64, + address + ) + { LockedBalance[] memory locks = _getAllLocks(account); LockedBalance memory lock = locks[lockId - 1]; require(lockId <= locks.length, "out of index"); @@ -43,8 +54,8 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { if (locks.length == 0) { return 0; } - uint totalDeposit = 0; - for (uint lockId = 1; lockId <= locks.length; lockId++) { + uint256 totalDeposit = 0; + for (uint256 lockId = 1; lockId <= locks.length; lockId++) { totalDeposit += locks[lockId - 1].amountOfToken; } return totalDeposit; @@ -55,8 +66,8 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { if (locks.length == 0) { return 0; } - uint totalRewards = 0; - for (uint lockId = 1; lockId <= locks.length; lockId++) { + uint256 totalRewards = 0; + for (uint256 lockId = 1; lockId <= locks.length; lockId++) { totalRewards += IStakingHelper(stakingContract).getStreamClaimableAmountPerLock(streamId, account, lockId); } return totalRewards; @@ -67,8 +78,8 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { if (locks.length == 0) { return 0; } - uint totalVotes = 0; - for (uint lockId = 1; lockId <= locks.length; lockId++) { + uint256 totalVotes = 0; + for (uint256 lockId = 1; lockId <= locks.length; lockId++) { totalVotes += locks[lockId - 1].amountOfVoteToken; } return totalVotes; @@ -95,7 +106,7 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { function _weightedPenalty(uint256 lockEnd, uint256 timestamp) internal view returns (uint256) { Weight memory weight = _getWeight(); - uint maxLockPeriod = IStakingHelper(stakingContract).maxLockPeriod(); + uint256 maxLockPeriod = IStakingHelper(stakingContract).maxLockPeriod(); uint256 slopeStart = lockEnd; if (timestamp >= slopeStart) return 0; uint256 remainingTime = slopeStart - timestamp; diff --git a/contracts/dao/staking/interfaces/IStakingGetter.sol b/contracts/dao/staking/interfaces/IStakingGetter.sol index 6dada23..c0a8f34 100644 --- a/contracts/dao/staking/interfaces/IStakingGetter.sol +++ b/contracts/dao/staking/interfaces/IStakingGetter.sol @@ -8,9 +8,7 @@ import "../StakingStructs.sol"; interface IStakingGetter { function getUsersPendingRewards(address account, uint256 streamId) external view returns (uint256); - function getStream( - uint256 streamId - ) + function getStream(uint256 streamId) external view returns ( @@ -26,13 +24,17 @@ interface IStakingGetter { function getAllLocks(address account) external view returns (LockedBalance[] memory); - function getStreamClaimableAmountPerLock(uint256 streamId, address account, uint256 lockId) external view returns (uint256); + function getStreamClaimableAmountPerLock( + uint256 streamId, + address account, + uint256 lockId + ) external view returns (uint256); function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); - // function getStreamsCount() external view returns (uint256); + // function getStreamsCount() external view returns (uint256); - // function getLatestRewardsPerShare(uint256 streamId) external view returns (uint256); + // function getLatestRewardsPerShare(uint256 streamId) external view returns (uint256); function getWeight() external view returns (Weight memory); } diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index 106720d..8c77d46 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -22,7 +22,8 @@ interface IStakingHandler { address _owner, uint256[] memory scheduleTimes, uint256[] memory scheduleRewards, - uint256 tau) external; + uint256 tau + ) external; function proposeStream( address streamOwner, @@ -59,6 +60,8 @@ interface IStakingHandler { function withdrawPenalty(address penaltyReceiver) external; function updateVault(address _vault) external; + function emergencyUnlockAndWithdraw() external; + function createLocksForCouncils(CreateLockParams[] calldata lockParams) external; } diff --git a/contracts/dao/staking/library/RewardsLibrary.sol b/contracts/dao/staking/library/RewardsLibrary.sol index 0fd72ca..c251abd 100644 --- a/contracts/dao/staking/library/RewardsLibrary.sol +++ b/contracts/dao/staking/library/RewardsLibrary.sol @@ -58,7 +58,11 @@ library RewardsLibrary { return _getRewardsSchedule(stream, start, end); } - function _getRewardsSchedule(Stream memory stream, uint256 start, uint256 end) internal pure returns (uint256) { + function _getRewardsSchedule( + Stream memory stream, + uint256 start, + uint256 end + ) internal pure returns (uint256) { Schedule memory schedule = stream.schedule; uint256 startIndex; uint256 endIndex; diff --git a/contracts/dao/staking/library/StakingLibrary.sol b/contracts/dao/staking/library/StakingLibrary.sol index cee7433..3fddb2e 100644 --- a/contracts/dao/staking/library/StakingLibrary.sol +++ b/contracts/dao/staking/library/StakingLibrary.sol @@ -6,7 +6,11 @@ pragma solidity 0.8.13; import "../StakingStructs.sol"; library StakingLibrary { - function _caclulateAutoCompoundingShares(uint256 amount, uint256 totalShares, uint256 totalAmountOfStakedToken) internal pure returns (uint256) { + function _caclulateAutoCompoundingShares( + uint256 amount, + uint256 totalShares, + uint256 totalAmountOfStakedToken + ) internal pure returns (uint256) { uint256 _amountOfShares = 0; if (totalShares == 0) { _amountOfShares = amount; @@ -21,7 +25,12 @@ library StakingLibrary { return _amountOfShares; } - function _getWeightedPenalty(uint256 lockEnd, uint256 timestamp, Weight memory weight, uint256 maxLock) internal pure returns (uint256) { + function _getWeightedPenalty( + uint256 lockEnd, + uint256 timestamp, + Weight memory weight, + uint256 maxLock + ) internal pure returns (uint256) { uint256 slopeStart = lockEnd; if (timestamp >= slopeStart) return 0; uint256 remainingTime = slopeStart - timestamp; diff --git a/contracts/dao/staking/packages/RewardsCalculator.sol b/contracts/dao/staking/packages/RewardsCalculator.sol index 6bd1144..a924996 100644 --- a/contracts/dao/staking/packages/RewardsCalculator.sol +++ b/contracts/dao/staking/packages/RewardsCalculator.sol @@ -58,7 +58,11 @@ contract RewardsCalculator is IRewardsHandler { return _getRewardsSchedule(schedule, start, end); } - function _getRewardsSchedule(Schedule memory schedule, uint256 start, uint256 end) internal pure returns (uint256) { + function _getRewardsSchedule( + Schedule memory schedule, + uint256 start, + uint256 end + ) internal pure returns (uint256) { uint256 startIndex; uint256 endIndex; (startIndex, endIndex) = _getStartEndScheduleIndex(schedule, start, end); @@ -67,9 +71,7 @@ contract RewardsCalculator is IRewardsHandler { if (startIndex == endIndex) { // start and end are within the same schedule period reward = schedule.reward[startIndex] - schedule.reward[startIndex + 1]; - rewardScheduledAmount = FullMath.mulDiv( - reward, (end - start), - (schedule.time[startIndex + 1] - schedule.time[startIndex])); + rewardScheduledAmount = FullMath.mulDiv(reward, (end - start), (schedule.time[startIndex + 1] - schedule.time[startIndex])); rewardScheduledAmount = (reward * (end - start)) / (schedule.time[startIndex + 1] - schedule.time[startIndex]); } else { // start and end are not within the same schedule period @@ -83,9 +85,11 @@ contract RewardsCalculator is IRewardsHandler { rewardScheduledAmount += schedule.reward[startIndex + 1] - schedule.reward[endIndex]; // Reward at the end schedule where schedule.time[endIndex] ' reward = schedule.reward[endIndex] - schedule.reward[endIndex + 1]; - rewardScheduledAmount += FullMath.mulDiv(reward, - (end - schedule.time[endIndex]), - (schedule.time[endIndex + 1] - schedule.time[endIndex])); + rewardScheduledAmount += FullMath.mulDiv( + reward, + (end - schedule.time[endIndex]), + (schedule.time[endIndex + 1] - schedule.time[endIndex]) + ); } return rewardScheduledAmount; } @@ -96,7 +100,7 @@ contract RewardsCalculator is IRewardsHandler { uint256 end ) internal pure returns (uint256 startIndex, uint256 endIndex) { uint256 scheduleTimeLength = schedule.time.length; - require(scheduleTimeLength >=2, "bad schedules"); + require(scheduleTimeLength >= 2, "bad schedules"); require(end > start, "bad query period"); require(start >= schedule.time[0], "query before start"); require(end <= schedule.time[scheduleTimeLength - 1], "query after end"); diff --git a/contracts/dao/staking/packages/RewardsInternals.sol b/contracts/dao/staking/packages/RewardsInternals.sol index 650702e..0cb6f7f 100644 --- a/contracts/dao/staking/packages/RewardsInternals.sol +++ b/contracts/dao/staking/packages/RewardsInternals.sol @@ -16,7 +16,11 @@ contract RewardsInternals is StakingStorage, IStakingEvents { } } - function _moveRewardsToPending(address account, uint256 streamId, uint256 lockId) internal { + function _moveRewardsToPending( + address account, + uint256 streamId, + uint256 lockId + ) internal { LockedBalance storage lock = locks[account][lockId - 1]; require(streams[streamId].status == StreamStatus.ACTIVE, "inactive"); User storage userAccount = users[account]; diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index 3b10abf..be51e82 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -17,7 +17,11 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { return locks[account]; } - function getStreamClaimableAmountPerLock(uint256 streamId, address account, uint256 lockId) external view override returns (uint256) { + function getStreamClaimableAmountPerLock( + uint256 streamId, + address account, + uint256 lockId + ) external view override returns (uint256) { require(streams[streamId].status == StreamStatus.ACTIVE, "stream inactive"); require(lockId <= locks[account].length, "bad index"); uint256 latestRps = _getLatestRewardsPerShare(streamId); @@ -28,9 +32,7 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { return ((latestRps - userRpsPerLock) * userSharesOfLock) / RPS_MULTIPLIER; } - function getStream( - uint256 streamId - ) + function getStream(uint256 streamId) external view override diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 35429b8..01500e9 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -9,13 +9,16 @@ import "../StakingStorage.sol"; import "../interfaces/IStakingHandler.sol"; import "../vault/interfaces/IVault.sol"; import "../../../common/security/AdminPausable.sol"; + // solhint-disable not-rely-on-time contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, AdminPausable { bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); - constructor(){ + + constructor() { _disableInitializers(); } + /** * @dev initialize the contract and deploys the first stream of rewards * @dev initializable only once due to stakingInitialised flag @@ -36,7 +39,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A VoteCoefficient calldata voteCoef, uint256 _maxLocks, address _rewardsContract - ) external override initializer{ + ) external override initializer { rewardsCalculator = _rewardsContract; _initializeStaking(_mainToken, _voteToken, _weight, _vault, _maxLocks, voteCoef.voteShareCoef, voteCoef.voteLockCoef); require(IVault(vault).isSupportedToken(_mainToken), "Unsupported token"); @@ -51,16 +54,8 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A uint256[] memory scheduleTimes, uint256[] memory scheduleRewards, uint256 tau - ) external override onlyRole(STREAM_MANAGER_ROLE){ - _validateStreamParameters( - _owner, - mainToken, - scheduleRewards[MAIN_STREAM], - scheduleRewards[MAIN_STREAM], - scheduleTimes, - scheduleRewards, - tau - ); + ) external override onlyRole(STREAM_MANAGER_ROLE) { + _validateStreamParameters(_owner, mainToken, scheduleRewards[MAIN_STREAM], scheduleRewards[MAIN_STREAM], scheduleTimes, scheduleRewards, tau); uint256 streamId = 0; Schedule memory schedule = Schedule(scheduleTimes, scheduleRewards); streams.push( @@ -82,7 +77,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _adminPause(0); emit StreamProposed(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); emit StreamCreated(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); - } + } /** * @dev An admin of the staking contract can whitelist (propose) a stream. @@ -179,12 +174,10 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A emit StreamRemoved(streamId, stream.owner, stream.rewardToken); } - function createLocksForCouncils( - CreateLockParams[] calldata lockParams) public override onlyRole(DEFAULT_ADMIN_ROLE) - { - require(!councilsInitialized,"already created"); + function createLocksForCouncils(CreateLockParams[] calldata lockParams) public override onlyRole(DEFAULT_ADMIN_ROLE) { + require(!councilsInitialized, "already created"); councilsInitialized = true; - for(uint i = 0; i < lockParams.length; i++){ + for (uint256 i = 0; i < lockParams.length; i++) { address account = lockParams[i].account; prohibitedEarlyWithdraw[account][locks[account].length + 1] = true; _createLock(lockParams[i].amount, lockParams[i].lockPeriod, account); @@ -223,7 +216,6 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _earlyUnlock(lockId, msg.sender); prohibitedEarlyWithdraw[msg.sender][lockId] = false; } - function claimAllStreamRewardsForLock(uint256 lockId) public override pausable(1) { require(lockId <= locks[msg.sender].length, "bad lockid"); @@ -242,18 +234,14 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A User storage userAccount = users[msg.sender]; require(userAccount.pendings[streamId] != 0, "no pendings"); require(block.timestamp > userAccount.releaseTime[streamId], "not released"); - require(streams[streamId].status == StreamStatus.ACTIVE,"stream inactive"); + require(streams[streamId].status == StreamStatus.ACTIVE, "stream inactive"); _withdraw(streamId); } function withdrawAllStreams() public override pausable(1) { User storage userAccount = users[msg.sender]; for (uint256 i = 0; i < streams.length; i++) { - if ( - userAccount.pendings[i] != 0 && - block.timestamp > userAccount.releaseTime[i] && - streams[i].status == StreamStatus.ACTIVE) - { + if (userAccount.pendings[i] != 0 && block.timestamp > userAccount.releaseTime[i] && streams[i].status == StreamStatus.ACTIVE) { _withdraw(i); } } @@ -262,10 +250,10 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A /** * @dev Disregard rewards for emergency unlock and withdraw */ - function emergencyUnlockAndWithdraw() public override{ - require(paused != 0,"nt emergency"); + function emergencyUnlockAndWithdraw() public override { + require(paused != 0, "nt emergency"); uint256 numberOfLocks = locks[msg.sender].length; - for(uint lockId = 1;lockId <= numberOfLocks;lockId++){ + for (uint256 lockId = 1; lockId <= numberOfLocks; lockId++) { LockedBalance storage lock = locks[msg.sender][lockId]; uint256 stakeValue = lock.amountOfToken; _unlock(stakeValue, stakeValue, lockId, msg.sender); @@ -273,13 +261,12 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _withdraw(MAIN_STREAM); } - function updateVault(address _vault) public override onlyRole(DEFAULT_ADMIN_ROLE) { // enforce pausing this contract before updating the address. // This mitigates the risk of future invalid reward claims require(paused != 0, "require pause"); require(_vault != address(0), "zero addr"); - require(IVault(vault).migrated(),"nt migrated"); + require(IVault(vault).migrated(), "nt migrated"); vault = _vault; } @@ -288,7 +275,11 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _withdrawPenalty(penaltyReceiver); } - function _createLock(uint256 amount, uint256 lockPeriod, address account) internal { + function _createLock( + uint256 amount, + uint256 lockPeriod, + address account + ) internal { require(locks[account].length <= maxLockPositions, "max locks"); require(amount > 0, "amount 0"); require(lockPeriod <= maxLockPeriod, "max time"); @@ -297,7 +288,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A IVault(vault).deposit(msg.sender, mainToken, amount); } - function _verifyUnlock(uint256 lockId) internal view{ + function _verifyUnlock(uint256 lockId) internal view { require(lockId > 0, "zero lockid"); require(lockId <= locks[msg.sender].length, "bad lockid"); LockedBalance storage lock = locks[msg.sender][lockId - 1]; diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index c708227..c36663c 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -30,7 +30,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { require(_weight.maxWeightShares > _weight.minWeightShares, "bad share"); require(_weight.maxWeightPenalty > _weight.minWeightPenalty, "bad penalty"); require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "wrong weight"); - require(_voteLockCoef!=0,"zero coef"); + require(_voteLockCoef != 0, "zero coef"); mainToken = _mainToken; voteToken = _voteToken; weight = _weight; @@ -40,7 +40,11 @@ contract StakingInternals is StakingStorage, RewardsInternals { voteLockCoef = _voteLockCoef; } - function _lock(address account, uint256 amount, uint256 lockPeriod) internal { + function _lock( + address account, + uint256 amount, + uint256 lockPeriod + ) internal { uint256 nVoteToken; User storage userAccount = users[account]; if (lockPeriod > 0) { @@ -74,7 +78,12 @@ contract StakingInternals is StakingStorage, RewardsInternals { * @notice If the lock position is completely unlocked then the last lock is swapped with current locked * and last lock is popped off. */ - function _unlock(uint256 stakeValue, uint256 amount, uint256 lockId, address account) internal { + function _unlock( + uint256 stakeValue, + uint256 amount, + uint256 lockId, + address account + ) internal { User storage userAccount = users[account]; LockedBalance storage updateLock = locks[account][lockId - 1]; require(totalAmountOfStakedToken != 0, "Zero tokens"); @@ -109,7 +118,12 @@ contract StakingInternals is StakingStorage, RewardsInternals { * @notice the amount of stream shares you receive decreases from 100% to 25% * @notice the amount of stream shares you receive depends upon when in the timeline you have staked */ - function _stake(address account, uint256 amount, uint256 nVoteToken, uint256 lockId) internal { + function _stake( + address account, + uint256 amount, + uint256 nVoteToken, + uint256 lockId + ) internal { User storage userAccount = users[account]; LockedBalance storage lock = locks[account][lockId - 1]; @@ -121,14 +135,19 @@ contract StakingInternals is StakingStorage, RewardsInternals { uint256 streamsLength = streams.length; for (uint256 i = 0; i < streamsLength; i++) { - if(streams[i].status == StreamStatus.ACTIVE){ + if (streams[i].status == StreamStatus.ACTIVE) { userAccount.rpsDuringLastClaimForLock[lockId][i] = streams[i].rps; } } emit Staked(account, amount, weightedAmountOfSharesPerStream, nVoteToken, lockId, lock.end); } - function _unstake(uint256 amount, uint256 stakeValue, uint256 lockId, address account) internal { + function _unstake( + uint256 amount, + uint256 stakeValue, + uint256 lockId, + address account + ) internal { User storage userAccount = users[account]; LockedBalance storage updateLock = locks[account][lockId - 1]; totalAmountOfStakedToken -= stakeValue; @@ -152,7 +171,12 @@ contract StakingInternals is StakingStorage, RewardsInternals { } } - function _restakeThePosition(uint256 amountToRestake, uint256 lockId, LockedBalance storage updateLock, User storage userAccount) internal { + function _restakeThePosition( + uint256 amountToRestake, + uint256 lockId, + LockedBalance storage updateLock, + User storage userAccount + ) internal { totalAmountOfStakedToken += amountToRestake; updateLock.amountOfToken += BoringMath.to128(amountToRestake); ///@notice if you unstake, early or partial or complete, @@ -164,7 +188,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { uint256 streamsLength = streams.length; for (uint256 i = 0; i < streamsLength; i++) { // The new shares should not claim old rewards - if(streams[i].status == StreamStatus.ACTIVE){ + if (streams[i].status == StreamStatus.ACTIVE) { userAccount.rpsDuringLastClaimForLock[lockId][i] = streams[i].rps; } } @@ -192,7 +216,11 @@ contract StakingInternals is StakingStorage, RewardsInternals { totalPenaltyBalance += penalty; } - function _removeLockPosition(User storage userAccount, address account, uint256 lockId) internal { + function _removeLockPosition( + User storage userAccount, + address account, + uint256 lockId + ) internal { uint256 streamsLength = streams.length; uint256 lastLockId = locks[account].length; if (lastLockId != lockId && lastLockId > 1) { @@ -223,7 +251,11 @@ contract StakingInternals is StakingStorage, RewardsInternals { IVault(vault).payRewards(accountTo, mainToken, pendingPenalty); } - function _weightedShares(uint256 amountOfTokenShares, uint256 nVoteToken, uint256 timestamp) internal view returns (uint256) { + function _weightedShares( + uint256 amountOfTokenShares, + uint256 nVoteToken, + uint256 timestamp + ) internal view returns (uint256) { ///@notice Shares accomodate vote the amount of tokenShares and vote Tokens to be released ///@notice This formula makes it so that both the time locked for Main token and the amount of token locked /// is used to calculate rewards diff --git a/contracts/dao/staking/vault/interfaces/IVault.sol b/contracts/dao/staking/vault/interfaces/IVault.sol index 99d3381..d0d3333 100644 --- a/contracts/dao/staking/vault/interfaces/IVault.sol +++ b/contracts/dao/staking/vault/interfaces/IVault.sol @@ -2,21 +2,29 @@ pragma solidity 0.8.13; interface IVault { - function initVault(address _admin,address[] calldata supportedTokens) external; - - function deposit(address _user, address _token, uint256 _amount) external; - + function initVault(address _admin, address[] calldata supportedTokens) external; + + function deposit( + address _user, + address _token, + uint256 _amount + ) external; + function addRewardsOperator(address _rewardsOperator) external; function addSupportedToken(address _token) external; function removeSupportedToken(address _token) external; - function payRewards(address _user, address _token, uint256 _deposit) external; + function payRewards( + address _user, + address _token, + uint256 _deposit + ) external; function migrate(address vaultPackageMigrateTo) external; function isSupportedToken(address token) external view returns (bool); - function migrated() external view returns(bool); + function migrated() external view returns (bool); } diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index e32a3d5..7565395 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -8,6 +8,7 @@ import "../interfaces/IVaultEvents.sol"; import "../../../tokens/ERC20/IERC20.sol"; import "../../../../common/security/AdminPausable.sol"; import "../../../../common/SafeERC20.sol"; + // solhint-disable not-rely-on-time contract VaultPackage is IVault, IVaultEvents, AdminPausable { using SafeERC20 for IERC20; @@ -17,37 +18,46 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { mapping(address => bool) public override isSupportedToken; address[] public listOfSupportedTokens; bool public override migrated; - + constructor() { _disableInitializers(); } - function initVault(address _admin,address[] calldata supportedTokens) initializer external override { + + function initVault(address _admin, address[] calldata supportedTokens) external override initializer { require(!vaultInitialized, "Vault: Already Initialized"); vaultInitialized = true; - for (uint i = 0; i < supportedTokens.length; i++) { + for (uint256 i = 0; i < supportedTokens.length; i++) { _addSupportedToken(supportedTokens[i]); } pausableInit(0, _admin); } - function addRewardsOperator(address _rewardsOperator) external override onlyRole(DEFAULT_ADMIN_ROLE){ + function addRewardsOperator(address _rewardsOperator) external override onlyRole(DEFAULT_ADMIN_ROLE) { _grantRole(REWARDS_OPERATOR_ROLE, _rewardsOperator); } - function payRewards(address _user, address _token, uint256 _amount) external override pausable(1){ + function payRewards( + address _user, + address _token, + uint256 _amount + ) external override pausable(1) { require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "payRewards: No role"); require(isSupportedToken[_token], "Unsupported token"); - require(_amount!=0,"amount zero"); - require(deposited[_token] >= _amount,"payRewards: not enough deposit"); + require(_amount != 0, "amount zero"); + require(deposited[_token] >= _amount, "payRewards: not enough deposit"); deposited[_token] -= _amount; - IERC20(_token).safeTransfer(_user,_amount); + IERC20(_token).safeTransfer(_user, _amount); } - function deposit(address _user, address _token, uint256 _amount) external override pausable(1) { + function deposit( + address _user, + address _token, + uint256 _amount + ) external override pausable(1) { require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "deposit: No role"); require(isSupportedToken[_token], "Unsupported token"); deposited[_token] += _amount; - IERC20(_token).safeTransferFrom(_user, address(this),_amount); + IERC20(_token).safeTransferFrom(_user, address(this), _amount); } /// @notice adds token as a supproted rewards token by Vault @@ -60,26 +70,25 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { /// @notice removed token as a supproted rewards token by Treasury /// @param _token stream ERC20 token address - function removeSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) { + function removeSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) { require(isSupportedToken[_token], "Token does not exist"); - require(deposited[_token] == 0,"Token is still in use"); + require(deposited[_token] == 0, "Token is still in use"); isSupportedToken[_token] = false; _removeToken(_token); emit TokenRemoved(_token, msg.sender, block.timestamp); } /// @notice we believe newVaultPackage is safe - function migrate(address newVaultPackage) external override onlyRole(DEFAULT_ADMIN_ROLE){ - require(!migrated,"vault already migrated"); + function migrate(address newVaultPackage) external override onlyRole(DEFAULT_ADMIN_ROLE) { + require(!migrated, "vault already migrated"); require(paused != 0, "required pause"); - require(newVaultPackage != address(0),"withdrawTo: Zero addr"); - for(uint i = 0; i < listOfSupportedTokens.length;i++) - { + require(newVaultPackage != address(0), "withdrawTo: Zero addr"); + for (uint256 i = 0; i < listOfSupportedTokens.length; i++) { address token = listOfSupportedTokens[i]; uint256 balance = IERC20(token).balanceOf(address(this)); deposited[token] = 0; - IERC20(token).safeApprove(newVaultPackage,balance); - IVault(newVaultPackage).deposit(address(this), listOfSupportedTokens[i],balance); + IERC20(token).safeApprove(newVaultPackage, balance); + IVault(newVaultPackage).deposit(address(this), listOfSupportedTokens[i], balance); } migrated = true; } @@ -92,9 +101,9 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { } function _removeToken(address _token) internal { - for(uint i = 0; i < listOfSupportedTokens.length; i++) { - if(listOfSupportedTokens[i] == _token){ - listOfSupportedTokens[i] = listOfSupportedTokens[listOfSupportedTokens.length -1]; + for (uint256 i = 0; i < listOfSupportedTokens.length; i++) { + if (listOfSupportedTokens[i] == _token) { + listOfSupportedTokens[i] = listOfSupportedTokens[listOfSupportedTokens.length - 1]; break; } } diff --git a/contracts/dao/test/ERC20Rewards1.sol b/contracts/dao/test/ERC20Rewards1.sol index e736c6c..e422c7e 100644 --- a/contracts/dao/test/ERC20Rewards1.sol +++ b/contracts/dao/test/ERC20Rewards1.sol @@ -52,7 +52,12 @@ contract ERC20Rewards1 is Context, IERC20, IERC20Metadata { * All two of these values are immutable: they can only be set once during * construction. */ - constructor(string memory name_, string memory symbol_, uint totalSupply_, address _multiSigTreasury) { + constructor( + string memory name_, + string memory symbol_, + uint256 totalSupply_, + address _multiSigTreasury + ) { _name = name_; _symbol = symbol_; _totalSupply = totalSupply_; @@ -107,7 +112,11 @@ contract ERC20Rewards1 is Context, IERC20, IERC20Metadata { * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ - function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { + function transferFrom( + address from, + address to, + uint256 amount + ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); @@ -226,7 +235,11 @@ contract ERC20Rewards1 is Context, IERC20, IERC20Metadata { * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ - function _transfer(address from, address to, uint256 amount) internal virtual { + function _transfer( + address from, + address to, + uint256 amount + ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); @@ -306,7 +319,11 @@ contract ERC20Rewards1 is Context, IERC20, IERC20Metadata { * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ - function _approve(address owner, address spender, uint256 amount) internal virtual { + function _approve( + address owner, + address spender, + uint256 amount + ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); @@ -322,7 +339,11 @@ contract ERC20Rewards1 is Context, IERC20, IERC20Metadata { * * Might emit an {Approval} event. */ - function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { + function _spendAllowance( + address owner, + address spender, + uint256 amount + ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); @@ -346,7 +367,11 @@ contract ERC20Rewards1 is Context, IERC20, IERC20Metadata { * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ - function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} + function _beforeTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes @@ -362,5 +387,9 @@ contract ERC20Rewards1 is Context, IERC20, IERC20Metadata { * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ - function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} + function _afterTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} } diff --git a/contracts/dao/test/ERC20Rewards2.sol b/contracts/dao/test/ERC20Rewards2.sol index 12e0884..44955a3 100644 --- a/contracts/dao/test/ERC20Rewards2.sol +++ b/contracts/dao/test/ERC20Rewards2.sol @@ -53,7 +53,12 @@ contract ERC20Rewards2 is Context, IERC20, IERC20Metadata { * construction. */ - constructor(string memory name_, string memory symbol_, uint totalSupply_, address issuer) { + constructor( + string memory name_, + string memory symbol_, + uint256 totalSupply_, + address issuer + ) { _name = name_; _symbol = symbol_; _totalSupply = totalSupply_; @@ -108,7 +113,11 @@ contract ERC20Rewards2 is Context, IERC20, IERC20Metadata { * - the caller must have allowance for ``from``'s tokens of at least * `amount`. */ - function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { + function transferFrom( + address from, + address to, + uint256 amount + ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); @@ -227,7 +236,11 @@ contract ERC20Rewards2 is Context, IERC20, IERC20Metadata { * - `to` cannot be the zero address. * - `from` must have a balance of at least `amount`. */ - function _transfer(address from, address to, uint256 amount) internal virtual { + function _transfer( + address from, + address to, + uint256 amount + ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); @@ -307,7 +320,11 @@ contract ERC20Rewards2 is Context, IERC20, IERC20Metadata { * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ - function _approve(address owner, address spender, uint256 amount) internal virtual { + function _approve( + address owner, + address spender, + uint256 amount + ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); @@ -323,7 +340,11 @@ contract ERC20Rewards2 is Context, IERC20, IERC20Metadata { * * Might emit an {Approval} event. */ - function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { + function _spendAllowance( + address owner, + address spender, + uint256 amount + ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); @@ -347,7 +368,11 @@ contract ERC20Rewards2 is Context, IERC20, IERC20Metadata { * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ - function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} + function _beforeTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes @@ -363,5 +388,9 @@ contract ERC20Rewards2 is Context, IERC20, IERC20Metadata { * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ - function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} + function _afterTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} } diff --git a/contracts/dao/test/token-factory/ERC20Factory.sol b/contracts/dao/test/token-factory/ERC20Factory.sol index 7ea9048..0bb94ed 100644 --- a/contracts/dao/test/token-factory/ERC20Factory.sol +++ b/contracts/dao/test/token-factory/ERC20Factory.sol @@ -6,7 +6,11 @@ import "../../tokens/ERC20/ERC20.sol"; import "../../../common/access/AccessControl.sol"; contract Token is ERC20 { - constructor(string memory _name, string memory _ticker, uint256 _supply) ERC20(_name, _ticker) { + constructor( + string memory _name, + string memory _ticker, + uint256 _supply + ) ERC20(_name, _ticker) { _mint(msg.sender, _supply); } } @@ -22,7 +26,11 @@ contract ERC20Factory is IERC20Factory, AccessControl { _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); } - function deployToken(string calldata _name, string calldata _ticker, uint256 _supply) public override onlyRole(DEPLOYER_ROLE) returns (address) { + function deployToken( + string calldata _name, + string calldata _ticker, + uint256 _supply + ) public override onlyRole(DEPLOYER_ROLE) returns (address) { Token token = new Token(_name, _ticker, _supply); tokens.push(address(token)); diff --git a/contracts/dao/test/token-factory/interfaces/IERC20Factory.sol b/contracts/dao/test/token-factory/interfaces/IERC20Factory.sol index 731f253..0286e3b 100644 --- a/contracts/dao/test/token-factory/interfaces/IERC20Factory.sol +++ b/contracts/dao/test/token-factory/interfaces/IERC20Factory.sol @@ -2,5 +2,9 @@ pragma solidity 0.8.13; interface IERC20Factory { - function deployToken(string calldata _name, string calldata _ticker, uint256 _supply) external returns (address); + function deployToken( + string calldata _name, + string calldata _ticker, + uint256 _supply + ) external returns (address); } diff --git a/contracts/dao/test/token-timelock/TokenTimelock.sol b/contracts/dao/test/token-timelock/TokenTimelock.sol index 27ae2f6..6f65dc9 100644 --- a/contracts/dao/test/token-timelock/TokenTimelock.sol +++ b/contracts/dao/test/token-timelock/TokenTimelock.sol @@ -26,7 +26,11 @@ contract TokenTimelock is ITokenTimelock { // timestamp when token release is enabled uint256 private immutable _releaseTime; - constructor(IERC20 token_, address beneficiary_, uint256 releaseTime_) { + constructor( + IERC20 token_, + address beneficiary_, + uint256 releaseTime_ + ) { // solhint-disable-next-line require(releaseTime_ > block.timestamp, "TokenTimelock: release time is before current time"); _token = token_; diff --git a/contracts/dao/test/token-timelock/TokenTimelockFactory.sol b/contracts/dao/test/token-timelock/TokenTimelockFactory.sol index 2ca3a18..55f5380 100644 --- a/contracts/dao/test/token-timelock/TokenTimelockFactory.sol +++ b/contracts/dao/test/token-timelock/TokenTimelockFactory.sol @@ -18,11 +18,13 @@ contract TokenTimelockFactory is ITokenTimelockFactory, AccessControl { _grantRole(DEFAULT_ADMIN_ROLE, msg.sender); } - function deployTokenTimelocks( - address[] memory beneficiaries, - uint256[] memory releaseTimes - ) public override onlyRole(DEPLOYER_ROLE) returns (address[] memory) { - uint length = beneficiaries.length; + function deployTokenTimelocks(address[] memory beneficiaries, uint256[] memory releaseTimes) + public + override + onlyRole(DEPLOYER_ROLE) + returns (address[] memory) + { + uint256 length = beneficiaries.length; require(length == releaseTimes.length, "Wrong lengths"); address[] memory result = new address[](length); diff --git a/contracts/dao/tokens/ERC20/ERC20.sol b/contracts/dao/tokens/ERC20/ERC20.sol index 992eb9a..04bb6de 100644 --- a/contracts/dao/tokens/ERC20/ERC20.sol +++ b/contracts/dao/tokens/ERC20/ERC20.sol @@ -34,7 +34,11 @@ contract ERC20 is Context, IERC20, IERC20Metadata { return true; } - function transferFrom(address from, address to, uint256 amount) public virtual override returns (bool) { + function transferFrom( + address from, + address to, + uint256 amount + ) public virtual override returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, amount); _transfer(from, to, amount); @@ -84,7 +88,11 @@ contract ERC20 is Context, IERC20, IERC20Metadata { return _balances[account]; } - function _transfer(address from, address to, uint256 amount) internal virtual { + function _transfer( + address from, + address to, + uint256 amount + ) internal virtual { require(from != address(0), "ERC20: transfer from the zero address"); require(to != address(0), "ERC20: transfer to the zero address"); @@ -131,7 +139,11 @@ contract ERC20 is Context, IERC20, IERC20Metadata { _afterTokenTransfer(account, address(0), amount); } - function _approve(address owner, address spender, uint256 amount) internal virtual { + function _approve( + address owner, + address spender, + uint256 amount + ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); @@ -139,7 +151,11 @@ contract ERC20 is Context, IERC20, IERC20Metadata { emit Approval(owner, spender, amount); } - function _spendAllowance(address owner, address spender, uint256 amount) internal virtual { + function _spendAllowance( + address owner, + address spender, + uint256 amount + ) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { require(currentAllowance >= amount, "ERC20: insufficient allowance"); @@ -149,7 +165,15 @@ contract ERC20 is Context, IERC20, IERC20Metadata { } } - function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual {} + function _beforeTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} - function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual {} + function _afterTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual {} } diff --git a/contracts/dao/tokens/ERC20/IERC20.sol b/contracts/dao/tokens/ERC20/IERC20.sol index c57d77f..68a32d6 100644 --- a/contracts/dao/tokens/ERC20/IERC20.sol +++ b/contracts/dao/tokens/ERC20/IERC20.sol @@ -12,7 +12,11 @@ interface IERC20 { function approve(address spender, uint256 amount) external returns (bool); - function transferFrom(address from, address to, uint256 amount) external returns (bool); + function transferFrom( + address from, + address to, + uint256 amount + ) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); diff --git a/contracts/dao/tokens/ERC20/extensions/ERC20Permit.sol b/contracts/dao/tokens/ERC20/extensions/ERC20Permit.sol index 332435c..367b839 100644 --- a/contracts/dao/tokens/ERC20/extensions/ERC20Permit.sol +++ b/contracts/dao/tokens/ERC20/extensions/ERC20Permit.sol @@ -28,7 +28,15 @@ abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712 { return _domainSeparatorV4(); } - function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override { + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) public virtual override { // solhint-disable-next-line require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); diff --git a/contracts/dao/tokens/ERC20/extensions/ERC20Votes.sol b/contracts/dao/tokens/ERC20/extensions/ERC20Votes.sol index df4940d..351e75d 100644 --- a/contracts/dao/tokens/ERC20/extensions/ERC20Votes.sol +++ b/contracts/dao/tokens/ERC20/extensions/ERC20Votes.sol @@ -28,7 +28,14 @@ abstract contract ERC20Votes is IVotes, ERC20Permit { _delegate(_msgSender(), delegatee); } - function delegateBySig(address delegatee, uint256 nonce, uint256 expiry, uint8 v, bytes32 r, bytes32 s) public virtual override { + function delegateBySig( + address delegatee, + uint256 nonce, + uint256 expiry, + uint8 v, + bytes32 r, + bytes32 s + ) public virtual override { // solhint-disable-next-line require(block.timestamp <= expiry, "ERC20Votes: signature expired"); address signer = ECDSA.recover(_hashTypedDataV4(keccak256(abi.encode(_DELEGATION_TYPEHASH, delegatee, nonce, expiry))), v, r, s); @@ -76,7 +83,11 @@ abstract contract ERC20Votes is IVotes, ERC20Permit { _writeCheckpoint(_totalSupplyCheckpoints, _subtract, amount); } - function _afterTokenTransfer(address from, address to, uint256 amount) internal virtual override { + function _afterTokenTransfer( + address from, + address to, + uint256 amount + ) internal virtual override { super._afterTokenTransfer(from, to, amount); _moveVotingPower(delegates(from), delegates(to), amount); @@ -96,7 +107,11 @@ abstract contract ERC20Votes is IVotes, ERC20Permit { return type(uint224).max; } - function _moveVotingPower(address src, address dst, uint256 amount) private { + function _moveVotingPower( + address src, + address dst, + uint256 amount + ) private { if (src != dst && amount > 0) { if (src != address(0)) { (uint256 oldWeight, uint256 newWeight) = _writeCheckpoint(_checkpoints[src], _subtract, amount); diff --git a/contracts/dao/tokens/ERC20/extensions/IERC20Permit.sol b/contracts/dao/tokens/ERC20/extensions/IERC20Permit.sol index a202ade..c6a5569 100644 --- a/contracts/dao/tokens/ERC20/extensions/IERC20Permit.sol +++ b/contracts/dao/tokens/ERC20/extensions/IERC20Permit.sol @@ -5,7 +5,15 @@ pragma solidity 0.8.13; interface IERC20Permit { - function permit(address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external; + function permit( + address owner, + address spender, + uint256 value, + uint256 deadline, + uint8 v, + bytes32 r, + bytes32 s + ) external; function nonces(address owner) external view returns (uint256); diff --git a/contracts/dao/tokens/IVMainToken.sol b/contracts/dao/tokens/IVMainToken.sol index b1b3d5d..d7a6328 100644 --- a/contracts/dao/tokens/IVMainToken.sol +++ b/contracts/dao/tokens/IVMainToken.sol @@ -21,6 +21,8 @@ interface IVMainToken { function mint(address to, uint256 amount) external; function burn(address account, uint256 amount) external; + function grantMinterRole(address _minter) external; - function revokeMinterRole(address _minter) external; + + function revokeMinterRole(address _minter) external; } diff --git a/contracts/dao/tokens/MainToken.sol b/contracts/dao/tokens/MainToken.sol index 3dbb0dd..85aafb5 100644 --- a/contracts/dao/tokens/MainToken.sol +++ b/contracts/dao/tokens/MainToken.sol @@ -6,7 +6,12 @@ pragma solidity 0.8.13; import "./ERC20/ERC20.sol"; contract MainToken is ERC20 { - constructor(string memory name_, string memory symbol_, uint totalSupply_, address issuer) ERC20(name_, symbol_) { + constructor( + string memory name_, + string memory symbol_, + uint256 totalSupply_, + address issuer + ) ERC20(name_, symbol_) { _totalSupply = totalSupply_; _balances[issuer] = totalSupply_; diff --git a/contracts/dao/tokens/VMainToken.sol b/contracts/dao/tokens/VMainToken.sol index 39b624f..1f1295c 100644 --- a/contracts/dao/tokens/VMainToken.sol +++ b/contracts/dao/tokens/VMainToken.sol @@ -43,12 +43,13 @@ contract VMainToken is IVMainToken, Pausable, AccessControl, Initializable, ERC2 isWhiteListed[_toRemove] = false; emit MemberRemovedFromWhitelist(_toRemove); } - function grantMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)){ + + function grantMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)) { _grantRole(MINTER_ROLE, _minter); addToWhitelist(_minter); } - function revokeMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)){ + function revokeMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)) { _grantRole(MINTER_ROLE, _minter); removeFromWhitelist(_minter); } @@ -70,12 +71,20 @@ contract VMainToken is IVMainToken, Pausable, AccessControl, Initializable, ERC2 _burn(account, amount); } - function _beforeTokenTransfer(address from, address to, uint256 amount) internal override whenNotPaused { + function _beforeTokenTransfer( + address from, + address to, + uint256 amount + ) internal override whenNotPaused { require(isWhiteListed[msg.sender], "VMainToken: is intransferable unless the sender is whitelisted"); super._beforeTokenTransfer(from, to, amount); } - function _afterTokenTransfer(address from, address to, uint256 amount) internal override { + function _afterTokenTransfer( + address from, + address to, + uint256 amount + ) internal override { super._afterTokenTransfer(from, to, amount); } } diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index d77b055..b3cd844 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -13,23 +13,23 @@ contract MultiSigWallet is IMultiSigWallet { address to; bool executed; bytes data; - uint value; - uint numConfirmations; - uint expireTimestamp; + uint256 value; + uint256 numConfirmations; + uint256 expireTimestamp; } error TransactionRevered(bytes data); - uint public constant MAX_OWNER_COUNT = 50; + uint256 public constant MAX_OWNER_COUNT = 50; address[] public owners; address public governor; - uint public numConfirmationsRequired; - uint public lastDisabledTransactionIndex; + uint256 public numConfirmationsRequired; + uint256 public lastDisabledTransactionIndex; mapping(address => bool) public isOwner; - mapping(uint => mapping(address => bool)) public isConfirmed; + mapping(uint256 => mapping(address => bool)) public isConfirmed; mapping(address => bytes32) internal whitelistedBytesCode; @@ -40,27 +40,27 @@ contract MultiSigWallet is IMultiSigWallet { _; } - modifier txExists(uint _txIndex) { + modifier txExists(uint256 _txIndex) { require(_txIndex < transactions.length, "MultiSig: tx does not exist"); _; } - modifier notExecuted(uint _txIndex) { + modifier notExecuted(uint256 _txIndex) { require(!transactions[_txIndex].executed, "MultiSig: tx already executed"); _; } - modifier notConfirmed(uint _txIndex) { + modifier notConfirmed(uint256 _txIndex) { require(!isConfirmed[_txIndex][msg.sender], "MultiSig: tx already confirmed"); _; } - modifier notDisabled(uint _txIndex) { + modifier notDisabled(uint256 _txIndex) { require(_txIndex >= lastDisabledTransactionIndex, "MultiSig: old txs has been disabled"); _; } - modifier notExpired(uint _txIndex) { + modifier notExpired(uint256 _txIndex) { require(transactions[_txIndex].expireTimestamp >= block.timestamp || transactions[_txIndex].expireTimestamp == 0, "MultiSig: tx expired"); _; } @@ -70,7 +70,7 @@ contract MultiSigWallet is IMultiSigWallet { _; } - modifier validRequirement(uint ownerCount, uint _required) { + modifier validRequirement(uint256 ownerCount, uint256 _required) { require( ownerCount > 0 && ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && ownerCount > 1 ? _required > 1 : _required > 0, "MultiSig: Invalid requirement" @@ -85,9 +85,9 @@ contract MultiSigWallet is IMultiSigWallet { modifier validateSubmitTxInputs( address _to, - uint _value, + uint256 _value, bytes memory _data, - uint _expireTimestamp + uint256 _expireTimestamp ) { require(_expireTimestamp >= block.timestamp || _expireTimestamp == 0, "already expired"); @@ -102,13 +102,17 @@ contract MultiSigWallet is IMultiSigWallet { _; } - constructor(address[] memory _owners, uint _numConfirmationsRequired, address _governor) { + constructor( + address[] memory _owners, + uint256 _numConfirmationsRequired, + address _governor + ) { governor = _governor; require(_owners.length <= MAX_OWNER_COUNT, "owners limit reached"); require(_owners.length > 0, "owners required"); require(_numConfirmationsRequired > 0 && _numConfirmationsRequired <= _owners.length, "invalid number of required confirmations"); - for (uint i = 0; i < _owners.length; i++) { + for (uint256 i = 0; i < _owners.length; i++) { address owner = _owners[i]; require(owner != address(0), "invalid owner"); @@ -127,7 +131,7 @@ contract MultiSigWallet is IMultiSigWallet { function removeOwner(address owner) public override onlyWallet ownerExists(owner) { isOwner[owner] = false; - for (uint i = 0; i < owners.length - 1; i++) + for (uint256 i = 0; i < owners.length - 1; i++) if (owners[i] == owner) { owners[i] = owners[owners.length - 1]; break; @@ -141,10 +145,13 @@ contract MultiSigWallet is IMultiSigWallet { emit OwnerRemoval(owner); } - function addOwners( - address[] memory _owners - ) public override onlyWallet validRequirement(owners.length + _owners.length, numConfirmationsRequired + _owners.length) { - for (uint i = 0; i < _owners.length; i++) { + function addOwners(address[] memory _owners) + public + override + onlyWallet + validRequirement(owners.length + _owners.length, numConfirmationsRequired + _owners.length) + { + for (uint256 i = 0; i < _owners.length; i++) { address owner = _owners[i]; require(owner != address(0), "MultiSig: owner address == 0"); _requireNewOwner(owner); @@ -157,24 +164,24 @@ contract MultiSigWallet is IMultiSigWallet { changeRequirement(numConfirmationsRequired + _owners.length); } - function changeRequirement(uint _required) public override onlyWallet validRequirement(owners.length, _required) { + function changeRequirement(uint256 _required) public override onlyWallet validRequirement(owners.length, _required) { numConfirmationsRequired = _required; emit RequirementChange(_required); } function submitTransaction( address _to, - uint _value, + uint256 _value, bytes memory _data, - uint _expireTimestamp + uint256 _expireTimestamp ) public override onlyOwnerOrGov validateSubmitTxInputs(_to, _value, _data, _expireTimestamp) { - require(address(this).balance >= _value,"submitTransaction: not enough balance"); - if(!_to.isContract()){ - require(_value!= 0, "submitTransaction: value is zero"); - require(_data.length >0,"submitTransaction: not equal"); + require(address(this).balance >= _value, "submitTransaction: not enough balance"); + if (!_to.isContract()) { + require(_value != 0, "submitTransaction: value is zero"); + require(_data.length > 0, "submitTransaction: not equal"); } - uint txIndex = transactions.length; - + uint256 txIndex = transactions.length; + transactions.push( Transaction({ to: _to, value: _value, data: _data, executed: false, numConfirmations: 0, expireTimestamp: _expireTimestamp }) ); @@ -184,9 +191,16 @@ contract MultiSigWallet is IMultiSigWallet { emit SubmitTransaction(txIndex, msg.sender, _to, _value, _data); } - function confirmTransaction( - uint _txIndex - ) public override onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) notConfirmed(_txIndex) notDisabled(_txIndex) notExpired(_txIndex) { + function confirmTransaction(uint256 _txIndex) + public + override + onlyOwnerOrGov + txExists(_txIndex) + notExecuted(_txIndex) + notConfirmed(_txIndex) + notDisabled(_txIndex) + notExpired(_txIndex) + { Transaction storage transaction = transactions[_txIndex]; _requireTargetCodeNotChanged(transaction.to); @@ -197,9 +211,15 @@ contract MultiSigWallet is IMultiSigWallet { emit ConfirmTransaction(msg.sender, _txIndex); } - function executeTransaction( - uint _txIndex - ) public override onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) notDisabled(_txIndex) notExpired(_txIndex) { + function executeTransaction(uint256 _txIndex) + public + override + onlyOwnerOrGov + txExists(_txIndex) + notExecuted(_txIndex) + notDisabled(_txIndex) + notExpired(_txIndex) + { Transaction storage transaction = transactions[_txIndex]; _requireTargetCodeNotChanged(transaction.to); @@ -218,9 +238,15 @@ contract MultiSigWallet is IMultiSigWallet { emit ExecuteTransaction(msg.sender, _txIndex); } - function revokeConfirmation( - uint _txIndex - ) public override onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) notDisabled(_txIndex) notExpired(_txIndex) { + function revokeConfirmation(uint256 _txIndex) + public + override + onlyOwnerOrGov + txExists(_txIndex) + notExecuted(_txIndex) + notDisabled(_txIndex) + notExpired(_txIndex) + { Transaction storage transaction = transactions[_txIndex]; require(isConfirmed[_txIndex][msg.sender], "tx not confirmed"); @@ -235,13 +261,23 @@ contract MultiSigWallet is IMultiSigWallet { return owners; } - function getTransactionCount() public view override returns (uint) { + function getTransactionCount() public view override returns (uint256) { return transactions.length; } - function getTransaction( - uint _txIndex - ) public view override returns (address to, uint value, bytes memory data, bool executed, uint numConfirmations, uint expireTimestamp) { + function getTransaction(uint256 _txIndex) + public + view + override + returns ( + address to, + uint256 value, + bytes memory data, + bool executed, + uint256 numConfirmations, + uint256 expireTimestamp + ) + { Transaction memory transaction = transactions[_txIndex]; return (transaction.to, transaction.value, transaction.data, transaction.executed, transaction.numConfirmations, transaction.expireTimestamp); diff --git a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol index 10b0186..b2a07f3 100644 --- a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol +++ b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol @@ -4,14 +4,14 @@ pragma solidity 0.8.13; interface IMultiSigWallet { - event Deposit(address indexed sender, uint amount, uint balance); - event SubmitTransaction(uint indexed txIndex, address indexed owner, address indexed to, uint value, bytes data); - event ConfirmTransaction(address indexed owner, uint indexed txIndex); - event RevokeConfirmation(address indexed owner, uint indexed txIndex); - event ExecuteTransaction(address indexed owner, uint indexed txIndex); + event Deposit(address indexed sender, uint256 amount, uint256 balance); + event SubmitTransaction(uint256 indexed txIndex, address indexed owner, address indexed to, uint256 value, bytes data); + event ConfirmTransaction(address indexed owner, uint256 indexed txIndex); + event RevokeConfirmation(address indexed owner, uint256 indexed txIndex); + event ExecuteTransaction(address indexed owner, uint256 indexed txIndex); event OwnerRemoval(address indexed owner); event OwnerAddition(address indexed owner); - event RequirementChange(uint required); + event RequirementChange(uint256 required); receive() external payable; @@ -19,21 +19,33 @@ interface IMultiSigWallet { function addOwners(address[] calldata _owners) external; - function changeRequirement(uint _required) external; + function changeRequirement(uint256 _required) external; - function submitTransaction(address _to, uint _value, bytes memory _data, uint _expireTimestamp) external; + function submitTransaction( + address _to, + uint256 _value, + bytes memory _data, + uint256 _expireTimestamp + ) external; - function confirmTransaction(uint _txIndex) external; + function confirmTransaction(uint256 _txIndex) external; - function executeTransaction(uint _txIndex) external; + function executeTransaction(uint256 _txIndex) external; - function revokeConfirmation(uint _txIndex) external; + function revokeConfirmation(uint256 _txIndex) external; function getOwners() external returns (address[] memory); - function getTransactionCount() external returns (uint); - - function getTransaction( - uint _txIndex - ) external returns (address to, uint value, bytes memory data, bool executed, uint numConfirmations, uint expireTimestamp); + function getTransactionCount() external returns (uint256); + + function getTransaction(uint256 _txIndex) + external + returns ( + address to, + uint256 value, + bytes memory data, + bool executed, + uint256 numConfirmations, + uint256 expireTimestamp + ); } From 20d2396b310bd46564dce3447a8d293fed14071b Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 23 Jan 2023 17:57:06 +0545 Subject: [PATCH 25/77] reaudit fixes --- audit-report/Fathom_DAO-review.md | 1509 +++++++++++++++++ contracts/dao/governance/Governor.sol | 4 - .../dao/governance/MainTokenGovernor.sol | 18 +- .../extensions/GovernorTimelockControl.sol | 2 +- contracts/dao/staking/StakingStorage.sol | 1 + .../staking/helpers/StakingGettersHelper.sol | 7 +- .../dao/staking/interfaces/IStakingGetter.sol | 26 +- .../dao/staking/packages/RewardsInternals.sol | 2 - .../dao/staking/packages/StakingGetters.sol | 55 +- .../dao/staking/packages/StakingHandler.sol | 11 +- .../dao/staking/packages/StakingInternals.sol | 2 +- .../dao/staking/vault/interfaces/IVault.sol | 2 + .../staking/vault/packages/VaultPackage.sol | 21 +- contracts/dao/tokens/IVMainToken.sol | 4 - contracts/dao/tokens/VMainToken.sol | 24 +- contracts/dao/treasury/MultiSigWallet.sol | 1 + 16 files changed, 1613 insertions(+), 76 deletions(-) create mode 100644 audit-report/Fathom_DAO-review.md diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md new file mode 100644 index 0000000..89e4fbb --- /dev/null +++ b/audit-report/Fathom_DAO-review.md @@ -0,0 +1,1509 @@ +--- +Logo: https://i.imgur.com/ju7tCFh.png +Date: January 18, 2023 +--- + +# Fathom DAO + +[TOC] + +## Intro + +### Disclaimer +The audit makes no statements or warranties about the utility of the code, safety of the code, suitability of the business model, investment advice, endorsement of the platform or its products, regulatory regime for the business model, or any other statements about the fitness of the contracts to purpose, or their bug free status. The audit documentation is for discussion purposes only. + +### About Oxorio + +Oxorio is a young but rapidly growing audit and consulting company in the field of the blockchain industry, providing consulting and security audits for organizations from all over the world. Oxorio has participated in multiple blockchain projects during which smart contract systems were designed and deployed by the company. + +Oxorio is the creator, maintainer, and major contributor of several blockchain projects and employs more than 5 blockchain specialists to analyze and develop smart contracts. + +Our contacts: + +- [oxor.io](https://oxor.io) +- [ping@oxor.io](mailto:ping@oxor.io) +- [Github](https://github.com/oxor-io) +- [Linkedin](https://linkedin.com/company/oxor) +- [Twitter](https://twitter.com/Oxorio_audits) + + +### Security Assessment Methodology + +A group of auditors is involved in the work on this audit. Each of them checks the provided source code independently of each other in accordance with the security assessment methodology described below: + +**1. Project architecture review** + +Study the source code manually to find errors and bugs. + +**2. Check the code for known vulnerabilities from the list** + +Conduct a verification process of the code against the constantly updated list of already known vulnerabilities maintained by the company. + +**3. Architecture and structure check of the security model** + +Study the project documentation and its comparison against the code including the study of the comments and other technical papers. + +**4. Result’s cross-check by different auditors** + +Normally the research of the project is done by more than two auditors. This is followed by a step of mutual cross-check process of the audit results between different task performers. + +**5. Report consolidation** + +Consolidation of the audited report from multiple auditors. + +**6. Reaudit of new editions** + +After the provided review and fixes from the client, the found issues are being double-checked. The results are provided in the new version of the audit. + +**7. Final audit report publication** + +The final audit version is provided to the client and also published on the official website of the company. + + +### Findings Classification + +#### Severity Level Reference +The following severity levels were assigned to the issues described in the report: + +* **CRITICAL**: A bug leading to assets theft, locked fund access, or any other loss of funds due to transfer to unauthorized parties. +* **MAJOR**: A bug that can trigger a contract failure. Further recovery is possible only by manual modification of the contract state or replacement. +* **WARNING**: A bug that can break the intended contract logic or expose it to DDoS attacks. +* **INFO**: Minor issue or recommendation reported to / acknowledged by the client's team. + +#### Status Level Reference +Based on the feedback received from the client's team regarding the list of findings discovered by the contractor, the following statuses were assigned to the findings: + +* **NEW**: Waiting for the project team's feedback. +* **FIXED**: Recommended fixes have been applied to the project code and the identified issue no longer affects the project's security. +* **ACKNOWLEDGED**: The project team is aware of this finding. Recommended fixes for this finding are planned to be made. This finding does not affect the overall security of the project. +* **NO ISSUE**: Finding does not affect the overall security of the project and does not violate the logic of its work. +* **DISMISSED**: The issue or recommendation was dismissed by the client. + + +### Project overview +Fathom is a decentralized, community governed protocol. Locking FTHM tokens in DAO vault will allow you to put forward proposals and vote on them. + +### Audit Scope + +The scope of the audit includes the following smart contracts at: + +* [Treasury contracts](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/tree/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury) +* [Governance contracts](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/tree/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance) +* [DAO Tokens contracts](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/tree/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens) +* [Staking contracts](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/tree/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking) + +The original audited commit identifier is [`5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/commit/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/). + +The reaudited commit identifier with implemented Oxorio's recommendations is [`daa757804b549f91904ec18af91259f7fe434883`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/commit/daa757804b549f91904ec18af91259f7fe434883/). + + +## Findings Report + +### CRITICAL + +#### 1. [NEW] There's no `owners` array length validation in the constructor of `MultiSigWallet`[DONE] +##### Description +In the [MultiSigWallet\`s constructor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L76) there's no checking that the number of `owners` is less than or equal `MAX_OWNER_COUNT`. If the contract is created with `owners` with length more than `MAX_OWNER_COUNT` then that makes calls to `addOwner`, `changeRequirement` and `removeOwner` (which uses call `changeRequirement`) functions impossible because they use modifier `validRequirement` with this `require` statement: +```solidity +require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, "MultiSig: Invalid requirement"); +_; +``` +##### Recommendation +We recommend adding `owners` array length validation to `MultiSigWallet` constructor: +```solidity +require(_owners.length <= MAX_OWNER_COUNT, "owners limit reached"); +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +The implementation of the recommendation has led to new problems. + +In [`MultiSigWallet`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/treasury/MultiSigWallet.sol#L122) contract `constructor` misses `OwnerAddition` event. If external services or backend monitoring is used, `_owners` added with `constructor` will not be included in the statistics. + +We recommend adding the following line to `constructor`: + +```solidity +emit OwnerAddition(owner); +``` + +#### [FIXED] Adding a new owner doesn't change necessary amount of signatures in `MultiSigWallet` +##### Description +In the function [`addOwner`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L108) the owner is added without changing the parameter `numConfirmationsRequired`. In a situation, for example, where signatures of 2 out of 4 owners are required, it results in that when the owner is added, there will be 2 out of 5, and it requires less than a half of the signatures to manage the functions of the contract, so the contract could be compromised. + +##### Recommendation +We recommend adding this call into function `addOwner`: +```solidity +changeRequirement(numConfirmationsRequired+1); +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. with slight change: +```solidity +changeRequirement(numConfirmationsRequired + _owners.length); +``` + +#### 2. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE] +##### Description +In the function [`removeOwner`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L96) the owner is being removed without revocation of transaction signatures, where they've signed. This creates a situation where the signatures of non-existent owners may be used. For example, like in the following scenario: + +1. There are signatures of 3 out of 5 owners. +2. 3 owners opposed the signing of the transaction, and 2 owners approved it. +3. 3 owners called `removeOwner` for 2 owners, who previously signed the transaction. +4. Then, one of the 3 remaining owners , using signatures of non-existent owners are able to execute the transaction. + +##### Recommendation +We recommend adding signature revocation mechanisms for signatures of the removed owners to the function `removeOwner`. +##### Update +###### Fathom response +Implemented Auditors Recommendation. +###### Oxorio's response + +This logic disables all transactions up to the current moment. + +```solidity +modifier notDisabled(uint _txIndex) { + require(_txIndex >= lastDisabledTransactionIndex, "MultiSig: old txs has been disabled"); + _; +} +``` + +This allows to manipulate with transaction acceptance, for example, it is possible to execute a transaction that removes a user before executing a transaction that collects confirmations. Thus, the transaction that has collected confirmations will be disabled and will not be able to be executed. +We propose refactoring this code according to the recommendation. + +#### [FIXED] There is no function that implements the `_cancel` proposal in `MainTokenGovernor` +##### Description +The contract [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) lacks a function that would implement the internal function [`_cancel`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L91), that allows you to cancel the execution of `proposal` with `TimelockController`. This can make it impossible to cancel the execution of a potentially dangerous call. +##### Recommendation +We recommend adding logic that would allow you to cancel the execution of `proposal` and call the internal function `_cancel`. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### 3. [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE] +##### Description +A change of the `timelock` parameter in the [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L22) contract can lead to already executed `proposals` being able to be executed again. This is connected to the fact that the execution status of the transaction is saved only in the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, and the `GovernorTimelockControl` contract makes calls to the `TimelockController` functions to get the `proposals` status in the [`state`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L50) function. +##### Recommendation +We recommend adding a separate mapping to the `GovernorTimelockControl` contract that would save information about the status of `proposal` and functions that would allow to update that status. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +Added: +```solidity +mapping(uint256 => bool) private isProposalExecuted; +``` +###### Oxorio's response +The recommendation has not been fully implemented. + +We recommend changing the work with the [`state`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L61) function to: +`isProposalExecuted[proposalId] == true` + + +#### [FIXED] The `initVault` and `initAdminAndOperator` functions can be initialized from any address in the `VaultPackage` contract +##### Description +In the `VaultPackage` contract the [`initVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L18) and [`initAdminAndOperator`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L26) functions can be called from any address. This could result in a potential attacker being able to intercept control for both `initVault` and `initAdminAndOperator` calls. +##### Recommendation +We suggest two solutions to this problem: + +- Combine the `initVault` and `initAdminAndOperator` functions into one `initialize` function and pass `calldata` to the [VaultProxy](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/proxy/VaultProxy.sol#L7) constructor in the `_data` parameter. +- Make a call to the `initVault` function on behalf of the `DEFAULT_ADMIN_ROLE`, and pass the `initVault` parameters just as `calldata` in the [VaultProxy](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/proxy/VaultProxy.sol#L7) constructor. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] There is no check that `stream` is active in the `StakingHandler` contract +##### Description +In the `StakingHandler` contract the [`withdrawAllStreams`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L243) and [`withdrawStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L236) functions do not have a check that `stream` is active. In the case of `withdrawAllStreams` this causes the function to use the entire `streams` array each time with active and inactive `streams` and, if there are not enough tokens on `VaultPackage`, the entire transaction will be `reverted`. In the case of `withdrawStream`, this can lead to `reverted` transaction, or unauthorized withdrawal of tokens from `VaultPackage`. + +##### Recommendation +We recommend adding to the `withdrawAllStreams` and `withdrawStream` functions a check that the output from `stream` has the status `ACTIVE`. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] Calling the `updateConfig` function may block the work of the `StakingHandlers` contract +##### Description +Calling the function [`updateConfig`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L252) in the `StakingHandler` contract can disrupt its work. This is possible for the following reasons: + +- There is no validation of `_weight` values. `_weight` can be equal to `0` and break the calculation of `share` in `streams` for staking holders. This will result in incorrect calculation of the repayment of staked tokens and rewards when exiting the stacking, which will block the work of the contract. +- Updating the `voteToken` parameter will cause the contract to try to burn new `voteToken` tokens that are not on the balance when [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) is called. +- Updating the parameters `rewardsCalculator`, `voteShareCoef`, `maxLockPeriod`, `maxLockPositions` will also lead to incorrect calculations and contract blocking. + +##### Recommendation +We recommend discarding the `updateConfig` function and consider mechanisms for stacking migration to a new contract with a suspension of the contract work during migration, e.g. `emergencyExit`. +##### Update +###### Fathom's response +Implemented `emergencyUnlockAndWithdraw` applicable when contract is paused. + +### MAJOR + +#### [FIXED] In `MultiSigWallet` there's no parameter defining minimum amount of signatures +##### Description +The parameter [`_numConfirmationsRequired`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L77) is checked in the constructor and in the function [`changeRequirement`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L116), that is not equal to `0`, however, when multi-signature is set, it allows the value `1`, and the contract may be used by one of the `owners`. + +##### Recommendation +We recommend adding minimum quantity constant for necessary signatures, e.g. `MIN_CONFIRMATIONS` and check if the set value is greater than or equal to `MIN_CONFIRMATIONS`. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +```solidity +modifier validRequirement(uint ownerCount, uint _required) { + require( + ownerCount > 0 && ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && ownerCount > 1 ? _required > 1 : _required > 0, + "MultiSig: Invalid requirement" + ); + _; +} +``` + +#### 4. [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet` +##### Description[NOTDONE] +In the structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) there's no lifetime parameter `expired`, which is responsible for the period of time during which the transaction must be executed. Since transactions may be executed at random time and are not removed over time, frozen, previously not approved transactions can be executed after a certain time and cause an undesirable effect. +##### Recommendation +We recommend adding an individual parameter, which is responsible for the maximum time until the transaction can be executed, e.g. `expired` and check it before running transactions. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/treasury/MultiSigWallet.sol#L176) is not implemented correctly. +We meant the `lifetime` parameter, which is passed as a function parameter. + +`lifetime` must be greater than the minimum value and already be in the body of the function to get the value. + +`transactions[_txIndex].expireTimestamp = block.timestamp + lifetime` + +#### 5. [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[NOTDONE] +##### Description +In the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, Governance can take away the `TIMELOCK_ADMIN_ROLE` rights from the address `admin`. In the case of an attack on `Governance` and `Council` this would make it impossible to revoke the role from the captured contracts. +##### Recommendation +We recommend to consider a permissions policy or add the `DEFAULT_ADMIN_ROLE` for `admin` to be able to revoke the role in case of an attack. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/governance/TimelockController.sol#L57) was not fully implemented. +Admin role was added but not functions like `grantRole` and `revokeRole` for specific roles from the list of possible ones on behalf of `DEFAULT_ADMIN_ROLE`. +Only `TIMELOCK_ADMIN_ROLE` can change or delete `TIMELOCK_ADMIN_ROLE`, if the role was deleted from admin, then even having the `DEFAULT_ADMIN_ROLE` role, will not work with the built-in external functions of the `AccessControl` contract. + + +#### [FIXED] There is no validation for `maxTargets` when executing in `Governor` +##### Description +In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L142) function there is no validation of the maximum number of `targets`. This can cause `proposal` to have so many calls to external contracts that the execution transaction will face a "gas bomb" effect. This means a large amount of gas consumption or restricted gas limit block. +##### Recommendation +We recommend including the `maxTargets` parameter for `_targets`, the maximum number of `_targets` in the `proposal`. +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] There is no possibility to update `multisig` in `Governor` +##### Description +In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L34) contract there is no possibility to perform a migration to a new `multisig`. For example to a new version of the contract. +##### Recommendation +We recommend adding the `updateMultisig` function, but so that only the old `multisig` could call it. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE] +##### Description +There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. +##### Recommendation +We recommend adding the `emergencyExit` function to the contract, which can be called by Governance by majority vote without confirmation with `multisig`. The function can be called once, its call stops the work of the contract. After calling this function, recovery is only possible by migrating to a new contract. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. and added `emergencyStop` +###### Oxorio's response +An `emergencyStop` method has been added, but the problem still remains. + +- The method just calls the `pause()` function +- The method is called on behalf of `Multisig`, which can be compromised. + +The main idea of this function is to put the contract into an emergency exit state, which can only be restored by completely replacing the contract and the states. This is an extreme case, an emergency stop. There should be no possibility to `unpause` after `emergencyStop` call. +We propose refactoring this code according to the recommendation. + +#### [FIXED] It is possible to set a null address in `GovernorTimelockControl` when updating `timelock`. +##### Description +In the `GovernorTimelockControl` contract it is possible to set a null address when calling the function [`_updateTimelock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L111). This can make the execution of `proposals` not possible since it is done through `timelock`. It will be also not possible to recover or change `timelock`, since it needs the corresponding proposal to be executed, which is also not possible with a zero `timelock`. +##### Recommendation +We recommend adding a check that the address `newTimelock != address(0)` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +A redundant validation in the constructor in `GovernorTimelockControl`: +```solidity +require(address(timelockAddress) != address(0), "timelockAddress cant be zero address"); +``` +We recommend removing it because the same validation can be found in `_updateTimelock`. + + +#### [FIXED] There is no validation for null values for `newQuorumNumerator` in `GovernorVotesQuorumFraction` +##### Description +In the `GovernorVotesQuorumFraction` contract in the [`_updateQuorumNumerator`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol#L55) function it is possible to set `_quorumNumerator` to `0` value, which would lead to a complete voting stop. +##### Recommendation +We recommend adding a constant with the minimum allowable value of `_quorumNumerator` and perform a corresponding check in the `_updateQuorumNumerator` function. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + + +#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE] +##### Description +In the [VMainToken](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) contract, for mint tokens, calling account, in addition to having `MINTER_ROLE` rights, must also be in the `isWhiteListed` list, since the mint function calls `_mint,` which contains [`_beforeTokenTransfer`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65) call. +When `_beforeTokenTransfer` is called, it checks that the `msg.sender` address is in the `isWhiteListed` list. +In the case of `mint`, it is the address with the `MINTER_ROLE` rights. +The administrator can grant/revoke `MINTER_ROLE` from an address by calling `grantRole`/`revokeRole`, but the `isWhitelisted` list remains unchanged - the old address stays in the list while the new one is never added. +This creates a risk that if `MINTER_ROLE` is compromised by an attacker, the admin will not be able to correctly revoke his rights, and the attacker can make a `transfer` of tokens to unauthorized addresses. +##### Recommendation +We recommend adding separate functions to grant and revoke the `MINTER_ROLE`, which will also add and remove addresses from the `isWhitelisted` list. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +- When revoking minter rights, `_grantRole` is used instead of `_revokeRole`. It should be changed to: +```solidity +function revokeMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)) { + _revokeRole(MINTER_ROLE, _minter); +``` + +- To add and remove from whitelist the following functions are used: + +```solidity + function addToWhitelist(address _toAdd) public override onlyRole(WHITELISTER_ROLE) { + isWhiteListed[_toAdd] = true; + emit MemberAddedToWhitelist(_toAdd); + } + + function removeFromWhitelist(address _toRemove) public override onlyRole(WHITELISTER_ROLE) { + isWhiteListed[_toRemove] = false; + emit MemberRemovedFromWhitelist(_toRemove); + } + function grantMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)){ + _grantRole(MINTER_ROLE, _minter); + + addToWhitelist(_minter); + } + + function revokeMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)){ + _grantRole(MINTER_ROLE, _minter); + + removeFromWhitelist(_minter); + } +``` + +But it should be noted that `addToWhitelist` and `removeFromWhitelist` can be called from `WHITELISTER_ROLE`. In this case, `MINTER_ROLE` must also have `WHITELISTER_ROLE`. + +We recommend refactoring this code and adding internal functions `_addToWhitelist` and `_removeFromWhitelist` without access control to `grantMinterRole` and `revokeMinterRole`. + +#### 8. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[NOTDONE-CHECK] +##### Description +In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. +##### Recommendation +We recommend fixing the possibility of withdrawal of tokens of the `ERC20` standard from the balance of Governance. This can be done in the following way: + +- It is a must to implement the `addSupportingTokens` function due to the fact that various tokens of the `ERC20` standard can be transferred to the Governance balance. Governance must work only with trusted tokens like USDT, USDC, etc. This function will make it possible to create a list of trusted tokens. Adding a token should only be done through Governance. +- Add a check to the `execute` function to confirm that `_target` is the contract address from the trusted tokens. And only in this case pass it to the `TimelockController` address. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +The [`relay`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/governance/MainTokenGovernor.sol#L100) function is implemented incorrectly. +```solidity + function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance { + require(isSupportedToken[target],"relay: token not supported"); + (bool success, bytes memory returndata) = target.call{value: value}(data); + Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); + } +``` +Now it is possible to send value to a supported token contract. In this case all value sent to the token contract will be lost. +We recommend making two different functions for relaying `ERC20` tokens and native coins, e.g. `relayERC20` and `relayETH`. + + + +#### 9. [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE] +##### Description +The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol) contract lacks the ability to suspend a contract in an emergency and migrate assets to a new compatible `VaultPackage` contract. + +##### Recommendation +We recommend adding the `emergencyExit` function in the contract which permanently blocks contract function calls for `REWARD_OPERATOR_ROLE`, and adding the `migrate` function, which allows to move tokens and token balances to a new version of `VaultPackage`. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +The [migration](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/vault/packages/VaultPackage.sol#L82) flow is not complete. + +- After migration, `Vault` can still be used. +We recommend forbidding to use functions after migration. +- At the [`VaultPackage#L89`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/vault/packages/VaultPackage.sol#L89) `migrate` function is using balance of the `Vault` tokens instead of `deposited` mapping. In this case, during the migration, the tokens that got into the contract by accident will become deposited tokens of the new `Vault` and will be used as rewards. + +We recommend using `deposited` variable instead `balanceOf` `VaultPackage` balance. + + +#### 10. [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE] +##### Description +In the `StakingHandlers` contract, calling the function [`updateVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L269) can cause all contract functions that work with balances and `VaultPackage` functions to be blocked. +##### Recommendation +We recommend improving this function in the following way: + +- The `VaultPackage` update must be available if the current `VaultPackage` is put into `emergencyExit` status (see recommendation to this issue). +- Updating `VaultPackage` must only take place after calling the `migrate` function in the old `VaultPackage`. +- Updating `VaultPackage` must only take place if the migration of balances to the new `VaultPackage` was successful. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/packages/StakingHandler.sol#L264) has not been fully implemented. +```solidity + function updateVault(address _vault) public override onlyRole(DEFAULT_ADMIN_ROLE) { + // enforce pausing this contract before updating the address. + // This mitigates the risk of future invalid reward claims + require(paused != 0, "require pause"); + require(_vault != address(0), "zero addr"); + require(IVault(vault).migrated(), "nt migrated"); + vault = _vault; + } +``` + +Despite checking that the `vault` is migrated, there is no validation that `_vault` is a compatible `VaultPackage`, which is the contract where the migration took place. +We recommend adding new statement that `_vault` is `VaultPackage` for migration. + +#### [FIXED] There is no emergency suspension of the rewards payment in the `VaultPackage` contract +##### Description +In the `VaultPackage` contract there is no possibility to suspend the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31). This causes the attacker to continue taking tokens from the contract if the address with `REWARDS_OPERATOR_ROLE`, such as `StakingHandlers` contract, is compromised. + +##### Recommendation +We recommend adding the `pausable` modifier to the `payRewards` function of the `VaultPackage` contract. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] Unsafe use of the `transfer` and `transferFrom` functions in `StakingHandlers` and `VaultPackage` +##### Description +In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L34) and [VaultPackage](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) contracts there are unsafe `transfer` and `transferFrom` functions of the `ERC20` standard. The use of these functions is not recommended as not all tokens clearly comply with the `ERC20` standard, more details [here](https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca). +##### Recommendation +We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) extension from the OpenZepplin library and replace the `transfer` and `transferFrom` calls with `safeTransfer` and `safeTransferFrom`. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE-CHECK] +##### Description +In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. + +##### Recommendation +We recommend: + +- adding a separate `deposit` function in the `VaultPackage` contract and make reward payments through the `deposited` parameter. +- adding a separate `withdraw` function that would allow the `DEFAULT_ADMIN_ROLE` address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). +- replacing [token transfers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) to `VaultPackage` in the `StakingHandlers` contract with calling the `deposit` function of the `VaultPackage` contract. It should have a prior `safeApprove` call to token in the `VaultPackage` contract. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +###### Oxorio's response +Recommendation has not been fully implemented. In the current version there is still no possibility to withdraw tokens that got into the contract by accident. +We recommend adding a separate withdraw function, that would allow the `DEFAULT_ADMIN_ROLE` +address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). + +#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE] +##### Description +In the `StakingHandlers` contract the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function does not allocate tokens for rewards `MAIN_STREAM`, as it happens when [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) is called. This may result in the block of the `withdrawStream` function call from the `MAIN_STREAM` of tokens and rewards for some users, if the amount in `VaultPackage` is less than the amount stated in `scheduleRewards`. +##### Recommendation +We recommend moving the initialization of `MAIN_STREAM` from `initializeStaking`, that can be called when creating [`StakingProxy`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/proxy/StakingProxy.sol#L7), to the `initializeMainStream` function, which can only be called by `STREAM_MANAGER_ROLE`. Before calling this function the work of the contract must be suspended. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +The implementation of the recommendation has led to new problems. `initializeMainStream` can be reinitialized in [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/packages/StakingHandler.sol#L57). `initializeMainStream` function is missing custom initialize modifier in order to prevent it from the reinitialization. Any manager with `STREAM_MANAGER_ROLE` can create a stream without proposing it. +We recommend adding custom `stakingInitializer` modifier in order to prevent future reinitializations of the main stream. + + +#### [FIXED] Updating `rpsDuringLastClaimForLock` for inactive `stream` in the `StakingInternals` contract +##### Description +In the `StakingInternals` contract when the `_stake` function is called the [calculation of `rpsDuringLastClaimForLock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L123) is done even for inactive `streams`. This can lead to both excessive gas consumption and denial of service if the number of `streams`, active and inactive, is too large. +##### Recommendation +We recommend adding a check that the `stream`, for which the check takes place, has `ACTIVE` status. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + + +#### [FIXED] There is a possibility for a manager to remove all streams in order to steal all pending rewards in `StakingHandlers` + +##### Description + +In the contract `StakingHandlers` in the [`removeStream`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L163-L178) function a manager can remove `stream` with pending rewards for users. This will result in users losing their pending rewards. + +##### Recommendation +We recommend adding logic to check that there are no pending rewards for users in the `stream` before it can be deleted. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + + +#### [FIXED] `MINTER_ROLE` and `WHITELISTER_ROLE` have the same value in the `VMainToken` + +##### Description + +In the contract [`VMainToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L14-L15) the `MINTER_ROLE` and `WHITELISTER_ROLE` constants have the same value: +```solidity +bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); +bytes32 public constant WHITELISTER_ROLE = keccak256("MINTER_ROLE"); +``` +When the role is set, the `WHITELISTER_ROLE` variable will in fact be set to the `MINTER_ROLE`. This will result in the user getting both roles and an address with `WHITELISTER_ROLE` being able to call the `mint` and `burn` functions. + +##### Recommendation + +We recommend updating the setting of `WHITELISTER_ROLE` constant: + +```Solidity +bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### 13. [NEW] Transaction should be marked as `executed` if the call fails[NOTDONE] + +##### Description + +In the contracts: + +- [`MultiSigWallet.sol#L137-L145)`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L137-L145) +- [`TimelockController.sol#L111`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) +- [`Governor.sol#L76`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) + +If the call fails, all the state changes of the contract will be reverted. It means that this call would not be marked as `executed` and can be repeated in the future, since it has enough confirmations. + +##### Recommendation +We recommend marking transaction as `executed` in all cases, removing lines with statement of revert failed transactions, and adding `data` value to event. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +For `TimelockController`, it makes sense to revert on fail of execute as it will make sure that the bad proposals are not marked executed if it fails. + +###### Oxorio's response +Recommendation was not implemented. +In the contracts + +- [`MultiSigWallet.sol#L232-L236`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/treasury/MultiSigWallet.sol#L232-L236) +- [`TimelockController.sol#L226`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/governance/TimelockController.sol#L226) +- [`Governor.sol#L430`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/governance/Governor.sol#L430) + +the failed call will lead to all the state changes of the contract to be reverted. It means that this call would not be marked as `executed` and can be repeated in the future, since it has enough confirmations. This can lead to unexpected behavior, the state of the blockchain could be changed and already executed failed transaction could be re-executed and be successful. +As for `TimelockController`, the revert on fail of `_execute` does not mark the proposal as bad proposal, e.g. if the call has logic connected with timestamps it may be reverted on the one block and be successful on the next block. + +We recommend marking transaction as `executed` in all cases, removing lines with statement of reverting the failed transactions, and adding `data` value to the event. If the status of the call is `false`, transaction should not be reverted. + +#### [FIXED] Admin role can be revoked forever by mistake in `VMainToken` + +##### Description + +In the contract `VMainToken` in the [`initToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L32) function, the value of `admin` can be the same as `msg.sender` and thus it becomes possible that an `admin` accidently revokes admin role from himself. + +##### Recommendation + +We recommend adding a check that `admin` is not equal to `msg.sender`. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] It is possible for attacker to create active locks to force users to reach the lock limit in `StakingHandlers` + +##### Description + +In the [`StakingHandler`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L180-L187) contract the attacker can create active locks for token holders with `createLockWithoutEarlyWithdraw` function by using max value for `lockPeriod` in multiple transactions. In this case user's locks limit can be reached and they will not be able to enter the staking until the end of the lock period. +##### Recommendation +We recommend: +1. Revising the logic of the `createLock` and `createLockWithoutEarlyWithdraw` functions and making a separate limit for creating a lock from a third-party address. +2. Or creating a lock from the `msg.sender` address. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### 14 .[NEW] `prohibitedEarlyWithdraw` is not set to `false` for `lockid` after unlocking in `StakingHandlers` +##### Description +In the function [`createLockWithoutEarlyWithdraw`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L181) in the `StakingHandlers` contract parameter `prohibitedEarlyWithdraw` for given `lockid` is set to `true`, but it does not update to `false` after unlocking later in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions. Since the value in the `locks` array is deleted after the unlock, all new values will be assigned the value of `prohibitedEarlyWithdraw`, regardless of whether the `createLockWithoutEarlyWithdraw` or `createLock` function is called. + +##### Recommendation +We recommend setting `prohibitedEarlyWithdraw[account][lockId]` to `false` before deleting value from `locks` array in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions: + +```solidity +prohibitedEarlyWithdraw[msg.sender][lockId] = false; +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +```solidity +prohibitedEarlyWithdraw[msg.sender][lockId] = false; +``` +There is no setting of `prohibitedEarlyWithdraw` to `false` for the `unlockPartially` method. + +At the same time, it can be found in the `earlyUnlock` method, but it is not needed there since this method only works when the value is already set to `false`. +We recommend adding `prohibitedEarlyWithdraw` to `unlockPartially` and removing it from `earlyUnlock` functions. + +#### [NO_ISSUE] Calling `unlock`, `earlyUnlock` and `unlockPartially` before `claimRewards` will result in loss of rewards in `StakingHandlers` +##### Description +In the contract `StakingHandlers` the following functions can cause a loss of rewards if they are called before `claimRewards`: + +- [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) +- [`earlyUnlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L207) +- [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) + +It is possible because: + +- `unlock` and `earlyUnlock` functions contain an internal call to the [`_unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L76), where `lock` with given `lockId` is [removed](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L146) +- in `unlockPartially` the `rpsDuringLastClaimForLock` for given `lockId` is [updated](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L150) + +As a result, rewards for given `lockId` will be lost. + +##### Recommendation +We recommend adding internal function `_claimRewards` and claim rewards with the calls to `unlock`, `earlyUnlock`, and `unlockPartially` functions. +##### Update +###### Fathom's response +Frontend is designed in a way that tells the user to claim all the rewards before unlocking it. So we accept the risk of rewards loss if the user ignores this notification. +You can try it on [dapp.fathom.fi](dapp.fathom.fi). + +#### [FIXED] Share weight drop formula is incorrect in `StakingInternals` + +##### Description + +In the `StakingInternals` contract [share weight drop formula](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L228) is incorrect: +```solidity +uint256 shares = amountOfTokenShares + (voteShareCoef * nVoteToken) / 1000; +uint256 slopeStart = streams[MAIN_STREAM].schedule.time[0] + ONE_MONTH; +uint256 slopeEnd = slopeStart + ONE_YEAR; +if (timestamp <= slopeStart) return shares * weight.maxWeightShares; +if (timestamp >= slopeEnd) return shares * weight.minWeightShares; +return + shares * + weight.maxWeightShares + + (shares * (weight.maxWeightShares - weight.minWeightShares) * (slopeEnd - timestamp)) / + (slopeEnd - slopeStart); +``` + +It appears that the weight of the shares should gradually fall over time from `weight.maxWeightShares` to `weight.minWeightShares`. + +However, the current formula implements a weight drop from (2*`weight.maxWeightShares` - `weight.minWeightShares`) to `weight.maxWeightShares`. + +##### Recommendation + +We recommend changing `weight.maxWeightShares` to `weight.minWeightShares` in weight drop formula: + +```solidity +return + shares * + weight.minWeightShares + + (shares * (weight.maxWeightShares - weight.minWeightShares) * (slopeEnd - timestamp)) / + (slopeEnd - slopeStart); +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### 15. [NEW] Penalty can be bigger than stake in the `StakingInternals`[DONE] + +##### Description + +In the contract `StakingInternals` there is a [penalty calculation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L181) in the `_earlyUnlock` function: + +```solidity +uint256 penalty = (weighingCoef * amount) / 100000; +user storage userAccount = users[account]; +userAccount.pendings[MAIN_STREAM] -= penalty; +``` + +The maximum value of the `weightingCoef` that it can take is `weight.penaltyWeightMultiplier * weight.maxWeightPenalty`. In this case, the weight parameters are not checked in any way during [initizalization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33). If they are set in a way that the product of `weight.penaltyWeightMultiplier * weight.maxWeightPenalty` is greater than `100000`, then the penalty will be greater than the amount, which in turn will lead to excessive pendings or overflow. + +##### Recommendation +We recommend adding the following check to `initializeStaking` and `updateConfig`: +```solidity +require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "Wrong penalty weight"); +``` +It is also worth moving the value of `100000` into a separate constant variable to improve the readability of the code. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +```solidity +require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "wrong weight"); +``` +The value of `weight` is checked before setting `weight = _weight`, so the result of multiplying `weight.penaltyWeightMultiplier * weight.maxWeightPenalty` will always be `0`. + +We recommend replacing the [validation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/packages/StakingInternals.sol#L32) to: +```solidity +require(_weight.penaltyWeightMultiplier * _weight.maxWeightPenalty <= 100000, "wrong weight"); +``` + +### WARNING + +#### [NO_ISSUE] Modifier `onlyOwnerOrGov` creates a complex confirmation structure in case of `Governance` calls in the `MultiSigWallet` +##### Description +The modifier [`onlyOwnerOrGov`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L29) uses the following construction: +```solidity +require(isOwner[msg.sender] || governor == msg.sender, "MultiSig: MultiSigWallet, onlyOwnerOrGov(): Neither owner nor governor"); +``` +that allows calling the following functions in the contract on behalf of Governance: + +- `submitTransaction` +- `confirmTransaction` +- `revokeConfirmation` + +However, `Governance` may commit contract calls only with [permission from `MultiSigWallet`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L173). + +The result is that, if `Governance` wants to call a transaction on a `MultiSigWallet` contract: + +- `Governance` creates `proposal` for a call to `MultiSigWallet`. +- `MultiSigWallet` after confirmation by owners must call `confirmProposal` on `Governance`. +- Then `Governance` may call one of `MultiSigWallet` functions. +- In this case, however, `MultiSigWallet` transaction execution still requires signature of `owners`. + +Schematically, is looks like the following: + +- To make a call for `MultiSigWallet` it takes steps: `Governance` -> `createProposal` -> `confirmProposal`. +- To execute `confirmProposal` it takes steps: `MultiSigWallet` -> `submitTransaction` -> `confirmTransaction` -> `executeTransaction`. +- To make a call for `MultiSigWallet` it requires the next steps from `Governance`: `Governance` -> `execute` -> `MultiSigWallet`. + +And so each function in the sequence: + +- `submitTransaction` +- `confirmTransaction` +- `revokeConfirmation` + + +##### Recommendation +We recommend removing `Governance` from this modifier and give the permission to `MultiSigWallet` administration to authorized representatives only, or review the logic of `Governance` and approving of `proposals` from `MultiSigWallet`. +##### Update +###### Fathom's response +Thats the way its designed + +#### 16. [NEW] No parameter check when adding transaction in `MultiSigWallet`[NOTDONE] +##### Description +In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. +Based on the logic of the contract, there may be the following cases: + +- `_to` is a `EOA` address, `_value != 0,` `_data = ""`. +- `_to` is a contract. + +##### Recommendation +We recommend adding parameter checking when adding a transaction according to possible cases of using `MultiSigWallet`. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/treasury/MultiSigWallet.sol#L94) is not implemented correctly. + + +```solidity +if (_to.isContract()) { + require(_data.length > 0, "no calldata for contract call"); +} else { + require(_data.length == 0 && _value > 0, "calldata for EOA call or 0 value"); +} +``` +This implementation prohibits transferring `ETH` to the contract's balance. Since in the current condition it is assumed that if `_to` is a contract, then `_data` must not be empty. + +#### [FIXED] Missing validation, that the bytecode of address `_to` did not change while running a transaction in `MultiSigWallet` +##### Description +In the functions [`confirmTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L129) and [`executeTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L137) there's no validation that the bytecode of address `_to` did not change as an EOA or smart contract. +In this case, the following situations are possible: + +- when the transaction was added with the parameter `_to` as an EOA address, i.e. with an empty bytecode, and when the transaction is executed, frontrunning may occur and the attacker may deploy to `_to` address a smart contract with malicious code, using [metamorphic contracts](https://mixbytes.io/blog/pitfalls-of-using-cteate-cteate2-and-extcodesize-opcodes) and `create2` opcodes. +- when the transaction was added with the parameter `_to` as a smart contract, and at the moment of transaction execution, frontrunning may occur, and the attacker may change the bytecode at the `_to` address for a smart contract with malicious code using [metamorphic contracts](https://mixbytes.io/blog/pitfalls-of-using-cteate-cteate2-and-extcodesize-opcodes) and `create2` opcodes. + +##### Recommendation +We recommend adding: + +- checking that `_to` is an EOA address and when `confirmTransaction` and `executeTransaction` if the contract isn't deployed into the adress, using [`isContract`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L36) from OpenZeppelin. +- checking that the contract's bytecode has not been changed, recording the bytecode hash into a separate mapping, e.g.: +```solidity +bytes32 codeHash; +assembly { + codeHash = extcodehash(_to); +} + +isWhitelistedBytesCode[_to] = codeHash; + +... +bytes32 codeHash; +assembly { codeHash := extcodehash(account) } + +return (codeHash != isWhitelistedBytesCode[_to]); +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] There's no ETH balance validation when adding a non-zero transaction `_value` in `MultiSigWallet` +##### Description +In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no verifying that `MultiSigWallet` account has the necessary amount on the balance for the transaction. In case of approval by `owners` , the transaction will be approved but not executed. + +##### Recommendation +We recommend adding balance check while adding a transaction with a non-zero value `_value`. + +#### [NEW] There is no time limit for executing proposal in `Governor` +##### Description +The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract has no parameters for the time limit on `proposal` execution. This can result in no longer relevant proposal being executed after a period of time. +##### Recommendation +We recommend adding the `lifetime` parameter, the runtime of `proposal`, and check it during the execution. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +We have not found a implemented corrections for this issue. +We recommend adding a lifetime parameter, the runtime of proposal, and check it during the execution. + + +#### [NO_ISSUE] There is no check for gas consumption in `Governor` +##### Description +In the [Governor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L142) contract, the `propose` function lacks a parameter and a check for gas limit for calls to `targets`. This could make it possible for a call to a vulnerable external contract to be able to loop the call and perform a DDoS attack with high gas consumption. + +##### Recommendation +Consider implementing the `gasLimit` parameter - the maximum gas amount for a call, for each of the `targets`. +##### Update +###### Fathom's response +We will have voting for proposal and multisig execution confirmation. Thats hard to DDoS there, so we won’t implement gas check. + +#### [FIXED] `confirmProposal` is possible for both active and inactive proposals in `Governor` +##### Description +In the `Governor` contract the function [`confirmProposal`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L173) can be called for both active and inactive proposals. +##### Recommendation +We recommend adding a check that the proposal is either successful or already scheduled in the `confirmProposal` function: +```solidity +ProposalState status = state(proposalId); +require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### 17. [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController` +##### Description +In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) contracts the `execute` functions do not check the `msg.value` balance value needed to execute `_targets`, which would result in gas consumption even if the amount of `ETH` is not enough. +##### Recommendation +We recommend adding: + +- a check that the `msg.value` passed to the `execute` function is greater than the total value needed for the execution of the `targets` calls in the proposal. +- a return of the remaining `ETH` balance to the sender of the transaction after the execution of `proposal`. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +The value of the transferred ETH is checked in the `TimelockController` contract when the `execute` method is executed, but is not checked for `executeBatch`, which is actually used in the contracts. +We propose refactoring this code according to the recommendation. + +#### [FIXED] There is no check for zero value for `_token`, `_multiSig` and `_timelock` in `Governor`, `GovernorTimelockControl`, `MainTokenGovernor` +##### Description +In the constructors of [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L67), [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L17) and [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L21) contracts it is possible to set zero values for `tokenAddress`, `_multiSig`, `timelock` contracts. + +This may cause that `_token`, `_multiSig` and `_timelock` can be set to a zero address by mistake and break the contract. Thus, it will not be possible to update these parameters because an update is only possible from `Governance`, and `Governance` will cannot update parameters if `_timelock` is zero. + +##### Recommendation +We recommend adding a validation that the `_token`, `_multiSig`, `_timelock` addresses in the constructor are not zero. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] There is no check for zero in `GovernorSettings._setProposalThreshold` +##### Description +In the [`_setProposalThreshold`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorSettings.sol#L59) function it is possible to set `_proposalThreshold` to `0`. This can lead to a proposer be able to create a proposal with no voting tokens on the balance, or with a minimum number of them (e.g. `1 wei`). This creates a DDoS attack threat. +##### Recommendation +We recommend adding a check that `newProposalThreshold` is not zero. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### 18. [NEW] There is no limit on the number of proposals for one proposer in `Governor` +##### Description +In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. +##### Recommendation +We recommend adding a limit to the number of proposals with `active` and `pending` status. +##### Update +###### Fathom's response +`nextAcceptableProposalTimestamp[msg.sender] = block.timestamp + proposalTimeDelay;` +###### Oxorio's response +The implemented fix does not fully resolve the problem. +The Proposer can still create an unlimited number of proposals. +We recommend adding a limit for pending proposals for one user. + +#### [FIXED] A missing check that tokens are on the balance when calling the `payRewards` function in the `VaultPackage` contract +##### Description +In the `VaultPackage` contract when calling the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31) there is no processing of errors such as: + +- There is no check that tokens are on the balance. +- There is no check that the value of `amount != 0`. + +##### Recommendation +We recommend adding a check that tokens are on the balance and that `amount != 0`, and return error using `custom errors` (`revert CustomError`) or with `require`. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [NO_ISSUE] There is no limit on the maximum number of active `streams` in the `StakingHandlers` contract +##### Description +In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) contract there is no limit on the maximum number of active `streams`. This creates a situation of an uncontrolled gas consumption when dealing with contract functions and can lead to DoS. +##### Recommendation +We recommend adding a parameter that would allow to limit the maximum number of active `streams`. +##### Update +###### Fathom's response +This will be handled by Stream Manager. +###### Oxorio's response +Although it was evident that `STREAM_MANAGER_ROLE` was not a completely secure address, there have been a number of recent cases when a particular role could be compromised. +We strongly recommend to consider adding appropriate features and validations as described earlier. + + +#### [FIXED] Incorrect processing of contract modifiers `Initializable` in the `StakingHanders` contract +##### Description +The contract [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) uses the `upgradeable proxy` template, at the same time the work with the modifiers of the `Initializable` contract, which is inherited from the `AdminPausable`, is not performed correctly. +##### Recommendation +We recommend adjusting the contract according to [OpenZeppelin's recommendations](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/Initializable.sol): + +- The contract constructor must contain a call to the `_disableInitializers` function to disable contract initialization at the implementation level and prevent an attacker from using the contract's implementation +- The initializer (in the case of the `StakingHandlers` contract it is `initializeStaking`) must contain the `initializer` modifier +- The initialiser of the parent contract must be with the `onlyInitializing` modifier (in the case of the `StakingHandlers` contract, it is a call to the `pausableInit` of the [`AdminPausable`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/security/AdminPausable.sol#L28) contract) +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] It is possible for any user to call `createStream` in the `StakingHandlers` contract +##### Description +In the `StakingHandlers` contract any user can call the function [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L134) and run `stream`. This bears a risk that attackers could mislead a potential user into giving `approve` to the `StakingHandlers` contract and force them to call `createStream`. `createStream` will charge the user the necessary amount of money for the rewards. +##### Recommendation +We recommend adding a condition that `createStream` can only be called from the `streamOwner` address. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### 19. [NEW] Possible overflow with calculations +##### Description +In the next lines there is a possible overflow: + +- [`RewardsLibrary.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L70) +- [`RewardsLibrary.sol#L71`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L71) +- [`RewardsLibrary.sol#L78`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L78) +- [`RewardsLibrary.sol#L8`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L84) +- [`RewardsCalculator.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L70) +- [`RewardsCalculator.sol#L77`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L77) +- [`RewardsCalculator.sol#L83`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L83) +- [`RewardsInternals.sol#L15`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsInternals.sol#L15) +- [`RewardsInternals.sol#L24-L25`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsInternals.sol#L24-L25) +- [`StakingInternals.sol#L47`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L47) +- [`StakingInternals.sol#L45`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L45) +- [`StakingInternals.sol#L227-L230`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L227-L230) + +##### Recommendation +We recommend to use [`muldiv`](https://xn--2-umb.com/21/muldiv/index.html) to multiply elements safely. +We also recommend to update `voteLockCoef` [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L42) and add checks that it is not zero (to prevent division by zero) and that it is not too big in order to avoid overflow in `BoringMath`. +##### Update +###### Fathom's response +Done where feasible for contract size +###### Oxorio's response +We recommend fixing these issues completely, if there is already a problem with the size of the contract, then the code needs to be refactored. + +#### [NO_ISSUE] Multiple `streams` can be active at the same time with the same parameters in `StakingHandler.sol ` +##### Description +In the contract [StakingHandler]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L103-L111) it is possible to add and activate `streams` with the same parameters. This can lead to duplicate `streams` with the same parameters executed by mistake. +##### Recommendation +We recommend adding checks that `stream` is added before submitting a new one. +##### Update +###### Fathom's response +This will be handled by Stream Manager. +###### Oxorio's response +Although it was evident that `STREAM_MANAGER_ROLE` was not a completely secure address, there have been a number of recent cases when a particular role could be compromised. +We strongly recommend to consider adding appropriate features and validations as described earlier. + + +#### [NO_ISSUE] There is no limit for the amount of schedules on streams in `StakingHandlers` + +##### Description + +There is no limit for the amount of schedules on streams in the contract [`StakingHandlers`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L103-L111). This can cause the block gas limit to be exceeded. + +##### Recommendation +We recommend limiting values of `scheduleTimes` or `scheduleRewards`. +##### Update +###### Fathom's response +This will be handled by Stream Manager. +###### Oxorio's response +Although it was evident that `STREAM_MANAGER_ROLE` was not a completely secure address, there have been a number of recent cases when a particular role could be compromised. +We strongly recommend to consider adding appropriate features and validations as described earlier. + + + +#### [FIXED] It is possible to remove tokens that are used by another contract in `VaultPackage` + +##### Description +Calling the [`removeSupportedToken`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L47-L51) function in the `VaultPackage` contract removes tokens which are used in the `StakingHandler` contract to pay rewards and staked tokens. + +##### Recommendation + +We recommend adding logic to check that tokens are not used in any other contract before removing them. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +### INFO + +#### 20. [NEW] There's no logging of reverted transactions in `MultiSigWallet` +##### Description +In the function [`executeConfirmation`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L144) there's no logging of failed transactions. +```solidity +(bool success, ) = transaction.to.call{ value: transaction.value }(transaction.data); +require(success, "tx failed"); +``` + +##### Recommendation +We recommend replace this construction for the next one: +```solidity +error TransactionRevered(bytes data); +... +(bool success, bytes data) = transaction.to.call{ value: transaction.value }(transaction.data); + +if (success) { + emit ExecuteTransaction(msg.sender, _txIndex); +} else { + revert TransactionRevered(data); +} +``` +This will allow monitoring of suspicious activity that involves using of `MultiSigWallet`. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +```solidity +if (success) { + emit ExecuteTransaction(msg.sender, _txIndex); +} else { + revert TransactionRevered(data); +} + +emit ExecuteTransaction(msg.sender, _txIndex); +``` +Two identical `ExecuteTransaction` events will be emitted on successful execution of the transaction. We recommend removing one from the [`MultiSigWallet#L218`]( https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/treasury/MultiSigWallet.sol#L231-L238). + + +#### [FIXED] Non-optimal packing of the `Transaction` structure in `MultiSigWallet` +##### Description + +The structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) uses a non-optimized storage layout. + +##### Recommendation +We recommend optimizing storage layout the following way: + +```solidity +struct Transaction { + address to; + bool executed; + bytes data; + uint value; + uint numConfirmations; +} +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] Incorrect status check in `execute` function in `Governor` +##### Description +In the [`execute`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) function there is an incorrect check of `Proposal` status: +```solidity +require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); +``` +In the [MainTokenGovernor.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract, that inherits from `Governor`, the execution is passed to the `TimelockController` contract. For a transaction to be executed through `TimelockController` it must only have the `ProposalState.Queued` status. Otherwise the gas will be wasted and the `execute` call will be reverted. +##### Recommendation +We recommend changing the status check for `Proposal`: +```solidity +require(status == ProposalState.Queued, "Governor: proposal not successful"); +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] `_minDelay` can be set to zero in `TimelockController` +##### Description +In the `TimelockController` contract the `_minDelay` parameter can be set to `0` during [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L67) and in the [`updateDelay`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L149) function. This will result in batch being able to be executed in the same block it was queued for execution. + +##### Recommendation +We recommend adding a check that `_minDelay != 0`. + +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] There is a redundant `initialized` check in `VMainToken` +##### Description +```solidity +require(!initialized, "already init"); +initialized = true; +``` +The [`initToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L24) function contains redundant code with checking and setting the value of the `initialized` parameter, since this check already exists in the `initializer` modifier in the `initToken` function. +##### Recommendation +We recommend deleting these lines. + +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] There is redundant code in the `VMainToken` contract +##### Description +The [`_mint`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L74) and [`_burn`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L78) functions in the `VMainToken` contract are redundant and essentially do not overload the parent functions. +##### Recommendation +We recommend deleting these functions. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [NO_ISSUE] The `Governor` and `TimeLockController` do not support the `ERC721` and `ERC1155` tokens +##### Description +The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contracts lack the following methods: + +```solidity +/** + * @dev See {IERC721Receiver-onERC721Received}. + */ +function onERC721Received( + address, + address, + uint256, + bytes memory +) public virtual override returns (bytes4) { + return this.onERC721Received.selector; +} + +/** + * @dev See {IERC1155Receiver-onERC1155Received}. + */ +function onERC1155Received( + address, + address, + uint256, + uint256, + bytes memory +) public virtual override returns (bytes4) { + return this.onERC1155Received.selector; +} + +/** + * @dev See {IERC1155Receiver-onERC1155BatchReceived}. + */ +function onERC1155BatchReceived( + address, + address, + uint256[] memory, + uint256[] memory, + bytes memory +) public virtual override returns (bytes4) { + return this.onERC1155BatchReceived.selector; +} +``` + +Thus `Governor` and `TimeLockController` do not support tokens with `ERC721` and `ERC1155` standards. +##### Recommendation +We recommend implementing these functions if the `Governor` and `TimeLockController` contracts require support for the `ERC721` and `ERC1155` tokens. And also create a list of trusted tokens that can work with (see above - `ERC20` standard tokens transfer possibility). +##### Update +###### Fathom's response +There is no provision for `ERC721` and `ERC1155` tokens to be deposited into the contract. + +#### [FIXED] The `addSupportedToken` and `removeSupportedToken` calls have an redundant `pausable` modifier in the `VaultPackage` contract +##### Description +In the `VaultPackage` contract the calls [`addSupportedToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L41) and [`removeSupportedToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L47) have a redundant modifier `pausable` since the calls are only possible from the `DEFAULT_ADMIN_ROLE` address and the modifier `pausable` contains the following condition +```solidity +require((paused & flag) == 0 || hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "paused contract"); +``` +where the `paused` condition will be ignored. + +##### Recommendation +We recommend reconsidering the `addSupportedToken` and `removeSupportedToken` function modifiers or removing the `pausable` modifier. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] There are no checks that `admin`, `proposers` and `executors` are not zero addresses in `TimelockController` + +##### Description + +In the contract [`TimelockController`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L49-L69) constructor there are no checks that `admin`, `proposers` and `executors` are not zero addresses. + +##### Recommendation + +We recommend adding checks that `admin`, `proposers` and `executors` are not zero addresses. + +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] Unused import of `StakingStructs` in `StakingStorage` + +##### Description + +[Import of `StakingStructs`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/StakingStorage.sol#L7) in the `StakingStorage`contract is never used. + + +##### Recommendation + +We recommend removing it to keep the codebase clean. + +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] Unused constant `ONE_MONTH` in `StakingGettersHelper` + +##### Description +The [`ONE_MONTH`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/helpers/StakingGettersHelper.sol#L13) constant in the `StakingGettersHelper` contract is never used. + +##### Recommendation +We recommend removing it to keep the codebase clean. + +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] Non-optimal storage layout for `Stream` struct in `StakingStructs` + +##### Description + +[`Stream` struct](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/StakingStructs.sol#L54-L66) in the `StakingStructs` contract has non-optimal storage layout. + +##### Recommendation +We recommend moving `StreamStatus` definition after the `rewardToken` line in the struct `Stream` in order to store values in one slot. +```solidity +struct Stream { + address owner; // stream owned by the ERC-20 reward token owner + address manager; // stream manager handled by Main stream manager role + address rewardToken; + StreamStatus status; + uint256 rewardDepositAmount; // the reward amount that has been deposited by a third party + uint256 rewardClaimedAmount; /// how much rewards have been claimed by stakers + uint256 maxDepositAmount; // maximum amount of deposit + uint256 minDepositAmount; // minimum amount of deposit + uint256 tau; // pending time prior reward release + uint256 rps; // Reward per share for a stream j>0 + Schedule schedule; +} +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [FIXED] Unnecessary `'` in a `RewardsLibrary` comment + +##### Description +There is an explicit `'` in the comment in [`RewardsLibrary.sol#L82`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L82) line. + +##### Recommendation +We recommend removing `'` from the comment. + +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + + +#### [NEW] There is a typo in a comment in `StakingInternals` + +##### Description + +There is a typo in the word "have" in the following line [`StakingInternals.sol#L95`]( +https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L95). + +```solidity +// user does not hae enough voteToken, it is still able to burn and unlock +``` + +##### Recommendation +We recommend changing it to: +```solidity +// user does not have enough voteToken, it is still able to burn and unlock +``` +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +Recommendation was not implemented, typo is still present in the word "have" in the following line [`StakingInternals#L105`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/packages/StakingInternals.sol#L105). + +We recommend changing it to: +```solidity +// user does not have enough voteToken, it is still able to burn and unlock +``` + + +#### [NEW] Redundant check for `maxDepositAmount > 0` in `RewardsCalculator` + +##### Description + +There is a redundant check for `maxDepositAmount > 0` in the next lines: + +- [RewardsCalculator.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L21-L23) +- [RewardsLibrary.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L21-L23) + +Since `minDepositAmount` is already greater than `0` and `maxDepositAmount` must be bigger than `minDepositAmount` there is no need to check that `maxDepositAmount > 0`. + +##### Recommendation + +We recommend removing requirement of `maxDepositAmount > 0` for gas savings and improving code readability. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response +The check remains in the [`RewardsLibrary#L21`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/library/RewardsLibrary.sol#L21): + +```solidity +require(maxDepositAmount > 0, "No Max Deposit"); +``` + +#### [NO_ISSUE] It is not possible to withdraw tokens that were sent by mistake + +##### Description + +It is not possible to withdraw tokens that were sent by mistake it the following contracts: + +- [`RewardsCalculator.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol) +- [`StakingPackage.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingPackage.sol) +- [`VMainToken.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) +- [`MainToken.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/MainToken.sol) + +##### Recommendation + +We recommend adding `sweep` function to withdraw tokens that were sent by mistake. + +##### Update +###### Fathom's response +There is no provision of tokens being sent in those contract. + + +#### [FIXED] Unused import of `ReentracyGuard` in `StakingHandlers` +##### Description +There is import of [`ReentracyGuard`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L11) in the `StakingHandlers` contract but `nonReentrant` from this class is never used in `StakingHandlers`. + +##### Recommendation +We recommend removing the unused import. + +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +#### [NEW] Сustom `initializer` modifier is used instead of one from OpenZeppelin + +##### Description + +It is better to use [Openzeppelin `initializer` ](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/Initializable.sol#L83) instead of custom modifiers in the next functions: + +- [`StakingHandler.sol#L33`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) +- [`VaultPackage.sol#L18`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L18) +- [`VMainToken.sol#L24`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L24) + +##### Recommendation + +We recommend using `initializer` and `initializable` modifiers from Openzeppelin instead of implementing custom modifiers. +##### Update +###### Fathom's response +Implemented Auditors Recommendation. +###### Oxorio's response + +The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/vault/packages/VaultPackage.sol#L27-L28) has not been fully implemented. + +```solidity +require(!vaultInitialized, "Vault: Already Initialized"); +vaultInitialized = true; +``` + +The `vaultInitialized` variable becomes meaningless after adding the `initializer` modifier to the `initVault` function in [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/vault/packages/VaultPackage.sol#L15) contract. +In [`VMainToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/tokens/VMainToken.sol#L16) contract `initToken` function uses `initializer`, additional `bool` variable `initialized` was not removed. + +We recommend removing custom `initializer` variables and validations. + + +#### [NO_ISSUE] Stream manager, treasury manager and admin represent the same account in `StakingHandlers` + +##### Description + +In the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function in the `StakingHandlers` contract multiple roles are assigned to the same `admin` address. + +##### Recommendation +We recommend to transfer treasury role after the deployment and the staking setting. Admin and manager of the initial `stream` should be two different roles. +##### Update +###### Fathom's response + +This is initial setup to make it easier. We will share roles after some time. + +#### [NO_ISSUE] Revert message strings are too long + +##### Description + +- [`VMainToken.sol#L65-L68`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65-L68) +- [`MultiSigWallet#L30`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L30) +- [`MultiSigWallet.sol#L55`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L55) +- [`MultiSigWallet.sol#L77`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L77) + +After the revert message string is split into 32-byte sized chunks and stored in `memory` using `mstore`, the `memory` offsets are given to `revert(offset, length)`. For chunks shorter than 32 bytes, and for low `--optimize-runs` values (usually even the default value of `200`), instead of using `push32(val)` (where `val` is the 32 byte hexadecimal representation of the string with zero padding on the least significant bits) the Solidity compiler replaces it by `shl(value, short-value)`, where `short-value` does not have any zero padding. This saves the total amount of bytes in the deploy code and therefore saves deploy time cost, at the expense of extra 6 gas consumption during runtime. +This means that shorter revert strings saves deploy time costs of the contract. Note that this is not relevant for high values of `--optimize-runs` since `push32` value will not be replaced by a `shl(value, short-value)` equivalent by the Solidity compiler. + +Going back, each 32 byte chunk of the string requires an extra `mstore`. That is, additional cost for `mstore`, `memory` expansion costs, as well as stack operations. Note that this runtime cost is only relevant when the revert condition is met. + +Overall, shorter revert strings can save deploy time as well as runtime costs. + +##### Recommendation + +We recommend making revert strings shorter. +Note that if your contracts already allow Solidity `0.8.4` and above, then consider using [custom errors](https://blog.soliditylang.org/2021/04/21/custom-errors). They provide more gas efficiency and also allow developers to describe the errors in detail using [NatSpec](https://docs.soliditylang.org/en/latest/natspec-format.html). The main disadvantage of this approach is that some tooling may not have proper support for it yet. +##### Update +###### Fathom's response +Not Done, right now. Lots of changes for revert strings might be required right now. + +#### [NO_ISSUE] Unnecessary reads from storage + +##### Description + +In the next lines using `MLOAD` and `MSTORE` to cache the variable in `memory` saves more gas than `SLOAD`, since they use only 3 gas, instead of the initial 100: + +- [`MultiSigWallet.sol#L138`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L138) +- [`StakingHandler.sol#L191`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L191) +- [`StakingHandler.sol#L200`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L200) +- [`StakingHandler.sol#L210`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L210) +- [`StakingHandler.sol#L237`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L237) +- [`StakingHandler.sol#L244`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L244) + + +##### Recommendation + +We recommend caching this storage variable in `memory` to reduce unnecessary reads from storage and save more gas. +##### Update +###### Fathom's response +Not Done, increases contract size. + +#### [FIXED] Misleading check `(scheduleTimeLength > 0)` in the `RewardsCalculator` + +##### Description + +In the function [`_getStartEndScheduleIndex`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L94) in the contract `RewardsCalculator` there is the following condition: +```solidity +require(scheduleTimeLength > 0, "bad schedules"); +``` + +This condition allows `scheduleTimeLength` value to be set to 1. This can lead to [underflow](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L105) and [incorrect operation of cycles](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L98) further down the code. + +##### Recommendation + +We recommend changing it to +```solidity +require(scheduleTimeLength >= 2, "bad schedules"); +``` +or completely remove this check, since this condition is already checked in `validateStreamParameters()` when the stream is created. + +##### Update +###### Fathom's response +Implemented Auditors Recommendation. + +## Conclusion + +The following table contains the total number of issues that were found during audit: + +[FINDINGS] + +Current audit revealed 75 issues of varying degrees of importance. For each founded issue the Contractor's team made recommendations on effective solving. \ No newline at end of file diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 1f27dd0..e00ed8a 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -246,10 +246,6 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { _pause(); } - function unpause() public onlyMultiSig { - _unpause(); - } - function getProposals(uint256 _numIndexes) public view diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index 0bd340b..7d8d8fe 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -97,12 +97,26 @@ contract MainTokenGovernor is * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. * Note that if the executor is simply the governor itself, use of `relay` is redundant. */ - function relay( + function relayERC20( address target, - uint256 value, bytes calldata data ) external payable virtual onlyGovernance { require(isSupportedToken[target], "relay: token not supported"); + (bool success, bytes memory returndata) = target.call(data); + Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); + } + + /** + * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor + * is some contract other than the governor itself, like when using a timelock, this function can be invoked + * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. + * Note that if the executor is simply the governor itself, use of `relay` is redundant. + */ + function relayNativeToken( + address target, + uint256 value, + bytes calldata data + ) external payable virtual onlyGovernance { (bool success, bytes memory returndata) = target.call{ value: value }(data); Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); } diff --git a/contracts/dao/governance/extensions/GovernorTimelockControl.sol b/contracts/dao/governance/extensions/GovernorTimelockControl.sol index 582631f..f42eada 100644 --- a/contracts/dao/governance/extensions/GovernorTimelockControl.sol +++ b/contracts/dao/governance/extensions/GovernorTimelockControl.sol @@ -58,7 +58,7 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { bytes32 queueid = _timelockIds[proposalId]; if (queueid == bytes32(0)) { return status; - } else if (_timelock.isOperationDone(queueid)) { + } else if (isProposalExecuted[proposalId] == true) { return ProposalState.Executed; } else if (_timelock.isOperationPending(queueid)) { return ProposalState.Queued; diff --git a/contracts/dao/staking/StakingStorage.sol b/contracts/dao/staking/StakingStorage.sol index 3a53328..0876015 100644 --- a/contracts/dao/staking/StakingStorage.sol +++ b/contracts/dao/staking/StakingStorage.sol @@ -42,6 +42,7 @@ contract StakingStorage { address public vault; address public rewardsCalculator; bool public councilsInitialized; + bool public mainStreamInitialized; ///Weighting coefficient for shares and penalties Weight internal weight; diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index 8e230c2..8e9ce45 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -12,12 +12,17 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { address private stakingContract; uint256 internal constant ONE_YEAR = 31536000; uint256 internal constant WEEK = 604800; - + uint256 public constant WEIGHT_SLOT = 14; constructor(address _stakingContract, address admin) { stakingContract = _stakingContract; _grantRole(DEFAULT_ADMIN_ROLE, admin); } + function getStreamSchedule(uint256 streamId) external view override + returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards){ + + } + function getLockInfo(address account, uint256 lockId) public view override returns (LockedBalance memory) { LockedBalance[] memory locks = _getAllLocks(account); require(lockId <= locks.length, "out of index"); diff --git a/contracts/dao/staking/interfaces/IStakingGetter.sol b/contracts/dao/staking/interfaces/IStakingGetter.sol index c0a8f34..e055564 100644 --- a/contracts/dao/staking/interfaces/IStakingGetter.sol +++ b/contracts/dao/staking/interfaces/IStakingGetter.sol @@ -8,19 +8,19 @@ import "../StakingStructs.sol"; interface IStakingGetter { function getUsersPendingRewards(address account, uint256 streamId) external view returns (uint256); - function getStream(uint256 streamId) - external - view - returns ( - address streamOwner, - address rewardToken, - uint256 rewardDepositAmount, - uint256 rewardClaimedAmount, - uint256 maxDepositAmount, - uint256 rps, - uint256 tau, - StreamStatus status - ); + // function getStream(uint256 streamId) + // external + // view + // returns ( + // address streamOwner, + // address rewardToken, + // uint256 rewardDepositAmount, + // uint256 rewardClaimedAmount, + // uint256 maxDepositAmount, + // uint256 rps, + // uint256 tau, + // StreamStatus status + // ); function getAllLocks(address account) external view returns (LockedBalance[] memory); diff --git a/contracts/dao/staking/packages/RewardsInternals.sol b/contracts/dao/staking/packages/RewardsInternals.sol index 0cb6f7f..3bd1904 100644 --- a/contracts/dao/staking/packages/RewardsInternals.sol +++ b/contracts/dao/staking/packages/RewardsInternals.sol @@ -27,7 +27,6 @@ contract RewardsInternals is StakingStorage, IStakingEvents { require(lock.amountOfToken != 0, "No Stake"); uint256 reward = ((streams[streamId].rps - userAccount.rpsDuringLastClaimForLock[lockId][streamId]) * lock.positionStreamShares) / RPS_MULTIPLIER; - if (reward == 0) return; // All rewards claimed or stream schedule didn't start userAccount.pendings[streamId] += reward; streamTotalUserPendings[streamId] += reward; @@ -65,7 +64,6 @@ contract RewardsInternals is StakingStorage, IStakingEvents { } } } - touchedAt = block.timestamp; } diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index be51e82..00495b8 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -32,38 +32,37 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { return ((latestRps - userRpsPerLock) * userSharesOfLock) / RPS_MULTIPLIER; } - function getStream(uint256 streamId) - external - view - override - returns ( - address streamOwner, - address rewardToken, - uint256 rewardDepositAmount, - uint256 rewardClaimedAmount, - uint256 maxDepositAmount, - uint256 rps, - uint256 tau, - StreamStatus status - ) - { - Stream storage stream = streams[streamId]; - return ( - stream.owner, - stream.rewardToken, - stream.rewardDepositAmount, - stream.rewardClaimedAmount, - stream.maxDepositAmount, - stream.rps, - stream.tau, - stream.status - ); - } + // function getStream(uint256 streamId) + // external + // view + // override + // returns ( + // address streamOwner, + // address rewardToken, + // uint256 rewardDepositAmount, + // uint256 rewardClaimedAmount, + // uint256 maxDepositAmount, + // uint256 rps, + // uint256 tau, + // StreamStatus status + // ) + // { + // Stream storage stream = streams[streamId]; + // return ( + // stream.owner, + // stream.rewardToken, + // stream.rewardDepositAmount, + // stream.rewardClaimedAmount, + // stream.maxDepositAmount, + // stream.rps, + // stream.tau, + // stream.status + // ); + // } function getStreamSchedule(uint256 streamId) external view override returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards) { return (streams[streamId].schedule.time, streams[streamId].schedule.reward); } - function getWeight() external view override returns (Weight memory) { return weight; } diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 01500e9..243d587 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -9,12 +9,14 @@ import "../StakingStorage.sol"; import "../interfaces/IStakingHandler.sol"; import "../vault/interfaces/IVault.sol"; import "../../../common/security/AdminPausable.sol"; +import "../../../common/SafeERC20.sol"; // solhint-disable not-rely-on-time contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, AdminPausable { + using SafeERC20 for address; bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); - + constructor() { _disableInitializers(); } @@ -55,6 +57,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A uint256[] memory scheduleRewards, uint256 tau ) external override onlyRole(STREAM_MANAGER_ROLE) { + require(!mainStreamInitialized,"init done"); _validateStreamParameters(_owner, mainToken, scheduleRewards[MAIN_STREAM], scheduleRewards[MAIN_STREAM], scheduleTimes, scheduleRewards, tau); uint256 streamId = 0; Schedule memory schedule = Schedule(scheduleTimes, scheduleRewards); @@ -73,8 +76,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A rps: 0 }) ); - IVault(vault).deposit(msg.sender, mainToken, scheduleRewards[0]); _adminPause(0); + mainStreamInitialized =true; + IVault(vault).deposit(msg.sender, mainToken, scheduleRewards[0]); emit StreamProposed(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); emit StreamCreated(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); } @@ -170,7 +174,6 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A stream.rewardToken, releaseRewardAmount <= rewardTreasury ? releaseRewardAmount : rewardTreasury // should not happen ); - emit StreamRemoved(streamId, stream.owner, stream.rewardToken); } @@ -205,6 +208,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _updateStreamRPS(); uint256 stakeValue = lock.amountOfToken; _unlock(stakeValue, amount, lockId, msg.sender); + prohibitedEarlyWithdraw[msg.sender][lockId] = false; } function earlyUnlock(uint256 lockId) public override pausable(1) { @@ -214,7 +218,6 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A require(lock.end > block.timestamp, "lock opened"); _updateStreamRPS(); _earlyUnlock(lockId, msg.sender); - prohibitedEarlyWithdraw[msg.sender][lockId] = false; } function claimAllStreamRewardsForLock(uint256 lockId) public override pausable(1) { diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index c36663c..0fbc705 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -29,7 +29,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { require(_weight.maxWeightShares > _weight.minWeightShares, "bad share"); require(_weight.maxWeightPenalty > _weight.minWeightPenalty, "bad penalty"); - require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "wrong weight"); + require(_weight.penaltyWeightMultiplier * _weight.maxWeightPenalty <= 100000, "wrong weight"); require(_voteLockCoef != 0, "zero coef"); mainToken = _mainToken; voteToken = _voteToken; diff --git a/contracts/dao/staking/vault/interfaces/IVault.sol b/contracts/dao/staking/vault/interfaces/IVault.sol index d0d3333..122a720 100644 --- a/contracts/dao/staking/vault/interfaces/IVault.sol +++ b/contracts/dao/staking/vault/interfaces/IVault.sol @@ -27,4 +27,6 @@ interface IVault { function isSupportedToken(address token) external view returns (bool); function migrated() external view returns (bool); + + function withdrawExtraTokens(address _token, address _withdrawTo) external; } diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index 7565395..c40fbeb 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -57,7 +57,7 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "deposit: No role"); require(isSupportedToken[_token], "Unsupported token"); deposited[_token] += _amount; - IERC20(_token).safeTransferFrom(_user, address(this), _amount); + IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount); } /// @notice adds token as a supproted rewards token by Vault @@ -78,6 +78,20 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { emit TokenRemoved(_token, msg.sender, block.timestamp); } + function withdrawExtraTokens(address _token, address _withdrawTo) external override onlyRole(DEFAULT_ADMIN_ROLE) { + uint256 balanceToWithdraw; + uint256 balanceInContract = IERC20(_token).balanceOf(address(this)); + if(isSupportedToken[_token] && balanceInContract > deposited[_token]){ + balanceToWithdraw = balanceInContract - deposited[_token]; + }else{ + balanceToWithdraw = balanceInContract; + } + + if(balanceToWithdraw > 0){ + IERC20(_token).transfer(_withdrawTo, balanceToWithdraw); + } + } + /// @notice we believe newVaultPackage is safe function migrate(address newVaultPackage) external override onlyRole(DEFAULT_ADMIN_ROLE) { require(!migrated, "vault already migrated"); @@ -85,10 +99,9 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { require(newVaultPackage != address(0), "withdrawTo: Zero addr"); for (uint256 i = 0; i < listOfSupportedTokens.length; i++) { address token = listOfSupportedTokens[i]; - uint256 balance = IERC20(token).balanceOf(address(this)); deposited[token] = 0; - IERC20(token).safeApprove(newVaultPackage, balance); - IVault(newVaultPackage).deposit(address(this), listOfSupportedTokens[i], balance); + IERC20(token).safeApprove(newVaultPackage, deposited[token]); + IVault(newVaultPackage).deposit(address(this),listOfSupportedTokens[i], deposited[token]); } migrated = true; } diff --git a/contracts/dao/tokens/IVMainToken.sol b/contracts/dao/tokens/IVMainToken.sol index d7a6328..b49e1ae 100644 --- a/contracts/dao/tokens/IVMainToken.sol +++ b/contracts/dao/tokens/IVMainToken.sol @@ -10,10 +10,6 @@ interface IVMainToken { function initToken(address _admin, address _minter) external; - function addToWhitelist(address _toAdd) external; - - function removeFromWhitelist(address _toRemove) external; - function pause() external; function unpause() external; diff --git a/contracts/dao/tokens/VMainToken.sol b/contracts/dao/tokens/VMainToken.sol index 1f1295c..b0cbf6e 100644 --- a/contracts/dao/tokens/VMainToken.sol +++ b/contracts/dao/tokens/VMainToken.sol @@ -34,24 +34,24 @@ contract VMainToken is IVMainToken, Pausable, AccessControl, Initializable, ERC2 emit MemberAddedToWhitelist(_minter); } - function addToWhitelist(address _toAdd) public override onlyRole(WHITELISTER_ROLE) { - isWhiteListed[_toAdd] = true; - emit MemberAddedToWhitelist(_toAdd); + function grantMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)) { + _grantRole(MINTER_ROLE, _minter); + _addToWhitelist(_minter); } - function removeFromWhitelist(address _toRemove) public override onlyRole(WHITELISTER_ROLE) { - isWhiteListed[_toRemove] = false; - emit MemberRemovedFromWhitelist(_toRemove); + function revokeMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)) { + _revokeRole(MINTER_ROLE, _minter); + _removeFromWhitelist(_minter); } - function grantMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)) { - _grantRole(MINTER_ROLE, _minter); - addToWhitelist(_minter); + function _addToWhitelist(address _toAdd) internal { + isWhiteListed[_toAdd] = true; + emit MemberAddedToWhitelist(_toAdd); } - function revokeMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)) { - _grantRole(MINTER_ROLE, _minter); - removeFromWhitelist(_minter); + function _removeFromWhitelist(address _toRemove) internal { + isWhiteListed[_toRemove] = false; + emit MemberRemovedFromWhitelist(_toRemove); } function pause() public override onlyRole(PAUSER_ROLE) { diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index b3cd844..ef82028 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -120,6 +120,7 @@ contract MultiSigWallet is IMultiSigWallet { isOwner[owner] = true; owners.push(owner); + emit OwnerAddition(owner); } numConfirmationsRequired = _numConfirmationsRequired; From 80bb8b7fa14b13e3da299df7b620da511416aac3 Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 23 Jan 2023 19:46:24 +0545 Subject: [PATCH 26/77] storage doing --- .../staking/helpers/IStakingGetterHelper.sol | 32 +-- .../staking/helpers/StakingGettersHelper.sol | 210 ++++++++++-------- .../dao/staking/interfaces/IStakingGetter.sol | 9 +- .../dao/staking/packages/StakingGetters.sol | 26 +-- .../dao/staking/packages/StakingHandler.sol | 4 +- .../staking/vault/packages/VaultPackage.sol | 2 +- 6 files changed, 154 insertions(+), 129 deletions(-) diff --git a/contracts/dao/staking/helpers/IStakingGetterHelper.sol b/contracts/dao/staking/helpers/IStakingGetterHelper.sol index dce197e..1708244 100644 --- a/contracts/dao/staking/helpers/IStakingGetterHelper.sol +++ b/contracts/dao/staking/helpers/IStakingGetterHelper.sol @@ -9,26 +9,26 @@ import "../interfaces/IStakingStorage.sol"; import "../../../common/security/IAdminPausable.sol"; interface IStakingGetterHelper { - function getLockInfo(address account, uint256 lockId) external view returns (LockedBalance memory); + // function getLockInfo(address account, uint256 lockId) external view returns (LockedBalance memory); - function getLock(address account, uint256 lockId) - external - view - returns ( - uint128, - uint128, - uint128, - uint64, - address - ); + // function getLock(address account, uint256 lockId) + // external + // view + // returns ( + // uint128, + // uint128, + // uint128, + // uint64, + // address + // ); - function getUserTotalDeposit(address account) external view returns (uint256); + // function getUserTotalDeposit(address account) external view returns (uint256); - function getStreamClaimableAmount(uint256 streamId, address account) external view returns (uint256); + // function getStreamClaimableAmount(uint256 streamId, address account) external view returns (uint256); - function getUserTotalVotes(address account) external view returns (uint256); + // function getUserTotalVotes(address account) external view returns (uint256); - function getFeesForEarlyUnlock(uint256 lockId, address account) external view returns (uint256); + // function getFeesForEarlyUnlock(uint256 lockId, address account) external view returns (uint256); - function getLocksLength(address account) external view returns (uint256); + // function getLocksLength(address account) external view returns (uint256); } diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index 8e9ce45..1a9fdac 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -13,101 +13,95 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { uint256 internal constant ONE_YEAR = 31536000; uint256 internal constant WEEK = 604800; uint256 public constant WEIGHT_SLOT = 14; - constructor(address _stakingContract, address admin) { - stakingContract = _stakingContract; - _grantRole(DEFAULT_ADMIN_ROLE, admin); - } - - function getStreamSchedule(uint256 streamId) external view override - returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards){ - - } - - function getLockInfo(address account, uint256 lockId) public view override returns (LockedBalance memory) { - LockedBalance[] memory locks = _getAllLocks(account); - require(lockId <= locks.length, "out of index"); - require(lockId > 0, "lockId cant be 0"); - return locks[lockId - 1]; - } - - function getLocksLength(address account) public view override returns (uint256) { - LockedBalance[] memory locks = _getAllLocks(account); - return locks.length; - } - - function getLock(address account, uint256 lockId) - public - view - override - returns ( - uint128, - uint128, - uint128, - uint64, - address - ) - { - LockedBalance[] memory locks = _getAllLocks(account); - LockedBalance memory lock = locks[lockId - 1]; - require(lockId <= locks.length, "out of index"); - require(lockId > 0, "lockId cant be 0"); - return (lock.amountOfToken, lock.amountOfVoteToken, lock.positionStreamShares, lock.end, lock.owner); - } - - function getUserTotalDeposit(address account) public view override returns (uint256) { - LockedBalance[] memory locks = _getAllLocks(account); - if (locks.length == 0) { - return 0; - } - uint256 totalDeposit = 0; - for (uint256 lockId = 1; lockId <= locks.length; lockId++) { - totalDeposit += locks[lockId - 1].amountOfToken; - } - return totalDeposit; - } - - function getStreamClaimableAmount(uint256 streamId, address account) public view override returns (uint256) { - LockedBalance[] memory locks = _getAllLocks(account); - if (locks.length == 0) { - return 0; - } - uint256 totalRewards = 0; - for (uint256 lockId = 1; lockId <= locks.length; lockId++) { - totalRewards += IStakingHelper(stakingContract).getStreamClaimableAmountPerLock(streamId, account, lockId); - } - return totalRewards; - } - - function getUserTotalVotes(address account) public view override returns (uint256) { - LockedBalance[] memory locks = _getAllLocks(account); - if (locks.length == 0) { - return 0; - } - uint256 totalVotes = 0; - for (uint256 lockId = 1; lockId <= locks.length; lockId++) { - totalVotes += locks[lockId - 1].amountOfVoteToken; - } - return totalVotes; - } - - function getFeesForEarlyUnlock(uint256 lockId, address account) public view override returns (uint256) { - LockedBalance[] memory locks = _getAllLocks(account); - require(lockId <= locks.length, "out of index"); - LockedBalance memory lock = locks[lockId - 1]; - require(lockId > 0, "lockId cant be 0"); - require(lock.end > block.timestamp, "lock opened, no penalty"); - - uint256 amount = lock.amountOfToken; - uint256 lockEnd = lock.end; - uint256 weighingCoef = _weightedPenalty(lockEnd, block.timestamp); - uint256 penalty = (weighingCoef * amount) / 100000; - return penalty; - } + // constructor(address _stakingContract, address admin) { + // stakingContract = _stakingContract; + // _grantRole(DEFAULT_ADMIN_ROLE, admin); + // } + + // function getLockInfo(address account, uint256 lockId) public view override returns (LockedBalance memory) { + // LockedBalance[] memory locks = _getAllLocks(account); + // require(lockId <= locks.length, "out of index"); + // require(lockId > 0, "lockId cant be 0"); + // return locks[lockId - 1]; + // } + + // function getLocksLength(address account) public view override returns (uint256) { + // LockedBalance[] memory locks = _getAllLocks(account); + // return locks.length; + // } + + // function getLock(address account, uint256 lockId) + // public + // view + // override + // returns ( + // uint128, + // uint128, + // uint128, + // uint64, + // address + // ) + // { + // LockedBalance[] memory locks = _getAllLocks(account); + // LockedBalance memory lock = locks[lockId - 1]; + // require(lockId <= locks.length, "out of index"); + // require(lockId > 0, "lockId cant be 0"); + // return (lock.amountOfToken, lock.amountOfVoteToken, lock.positionStreamShares, lock.end, lock.owner); + // } + + // function getUserTotalDeposit(address account) public view override returns (uint256) { + // LockedBalance[] memory locks = _getAllLocks(account); + // if (locks.length == 0) { + // return 0; + // } + // uint256 totalDeposit = 0; + // for (uint256 lockId = 1; lockId <= locks.length; lockId++) { + // totalDeposit += locks[lockId - 1].amountOfToken; + // } + // return totalDeposit; + // } + + // function getStreamClaimableAmount(uint256 streamId, address account) public view override returns (uint256) { + // LockedBalance[] memory locks = _getAllLocks(account); + // if (locks.length == 0) { + // return 0; + // } + // uint256 totalRewards = 0; + // for (uint256 lockId = 1; lockId <= locks.length; lockId++) { + // totalRewards += IStakingHelper(stakingContract).getStreamClaimableAmountPerLock(streamId, account, lockId); + // } + // return totalRewards; + // } + + // function getUserTotalVotes(address account) public view override returns (uint256) { + // LockedBalance[] memory locks = _getAllLocks(account); + // if (locks.length == 0) { + // return 0; + // } + // uint256 totalVotes = 0; + // for (uint256 lockId = 1; lockId <= locks.length; lockId++) { + // totalVotes += locks[lockId - 1].amountOfVoteToken; + // } + // return totalVotes; + // } + + // function getFeesForEarlyUnlock(uint256 lockId, address account) public view override returns (uint256) { + // LockedBalance[] memory locks = _getAllLocks(account); + // require(lockId <= locks.length, "out of index"); + // LockedBalance memory lock = locks[lockId - 1]; + // require(lockId > 0, "lockId cant be 0"); + // require(lock.end > block.timestamp, "lock opened, no penalty"); + + // uint256 amount = lock.amountOfToken; + // uint256 lockEnd = lock.end; + // uint256 weighingCoef = _weightedPenalty(lockEnd, block.timestamp); + // uint256 penalty = (weighingCoef * amount) / 100000; + // return penalty; + // } function _getAllLocks(address account) internal view returns (LockedBalance[] memory) { - LockedBalance[] memory locks = IStakingHelper(stakingContract).getAllLocks(account); - return locks; - } + + } function _weightedPenalty(uint256 lockEnd, uint256 timestamp) internal view returns (uint256) { Weight memory weight = _getWeight(); @@ -124,7 +118,33 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { maxLockPeriod); } - function _getWeight() internal view returns (Weight memory) { - return IStakingHelper(stakingContract).getWeight(); + function _getWeight() internal view returns (Weight memory returnWeight) { + bytes32 weight = IStakingHelper(stakingContract).readBySlot(WEIGHT_SLOT); + uint32 penaltyWeightMultiplier; + uint32 minWeightPenalty; + uint32 maxWeightPenalty; + uint32 minWeightShares; + uint32 maxWeightShares; + assembly { + let value := weight + let shifted := shr(96,value) + penaltyWeightMultiplier := and(0xffff, shifted) + shifted := shr(128,value) + minWeightPenalty := and(0xffff, shifted) + shifted := shr(160,value) + maxWeightPenalty := and(0xffff, shifted) + shifted := shr(192,value) + minWeightShares := and(0xffff, shifted) + shifted := shr(224,value) + maxWeightShares := and(0xffff, shifted) + } + + return Weight( + minWeightPenalty, + maxWeightPenalty, + minWeightShares, + maxWeightShares, + penaltyWeightMultiplier + ); } } diff --git a/contracts/dao/staking/interfaces/IStakingGetter.sol b/contracts/dao/staking/interfaces/IStakingGetter.sol index e055564..b03cdf5 100644 --- a/contracts/dao/staking/interfaces/IStakingGetter.sol +++ b/contracts/dao/staking/interfaces/IStakingGetter.sol @@ -6,7 +6,7 @@ pragma solidity 0.8.13; import "../StakingStructs.sol"; interface IStakingGetter { - function getUsersPendingRewards(address account, uint256 streamId) external view returns (uint256); + // function getUsersPendingRewards(address account, uint256 streamId) external view returns (uint256); // function getStream(uint256 streamId) // external @@ -30,11 +30,14 @@ interface IStakingGetter { uint256 lockId ) external view returns (uint256); - function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); + function readBySlot(uint256 slot) external view returns(bytes32); + function getAddressToList(uint256 slot,uint256 index, address account) external view returns(bytes memory value); + +// function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); // function getStreamsCount() external view returns (uint256); // function getLatestRewardsPerShare(uint256 streamId) external view returns (uint256); - function getWeight() external view returns (Weight memory); + // function getWeight() external view returns (Weight memory); } diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index 00495b8..7d5cb00 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -9,13 +9,6 @@ import "../interfaces/IStakingGetter.sol"; import "./StakingInternals.sol"; contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { - function getUsersPendingRewards(address account, uint256 streamId) external view override returns (uint256) { - return users[account].pendings[streamId]; - } - - function getAllLocks(address account) external view override returns (LockedBalance[] memory) { - return locks[account]; - } function getStreamClaimableAmountPerLock( uint256 streamId, @@ -32,6 +25,19 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { return ((latestRps - userRpsPerLock) * userSharesOfLock) / RPS_MULTIPLIER; } + function readBySlot(uint256 slot) external view override returns(bytes32 value) { + assembly { + value := sload(slot) + } + } + + function getAddressToList(uint256 slot,uint256 index, address account) external view override returns(bytes memory value){ + bytes32 location = keccak256(abi.encode(keccak256(abi.encode(account, slot)))); + assembly { + value := sload(add(location,index)) + } + } + // function getStream(uint256 streamId) // external // view @@ -60,10 +66,4 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { // ); // } - function getStreamSchedule(uint256 streamId) external view override returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards) { - return (streams[streamId].schedule.time, streams[streamId].schedule.reward); - } - function getWeight() external view override returns (Weight memory) { - return weight; - } } diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 243d587..db28230 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -77,8 +77,10 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A }) ); _adminPause(0); - mainStreamInitialized =true; IVault(vault).deposit(msg.sender, mainToken, scheduleRewards[0]); + mainStreamInitialized =true; + + emit StreamProposed(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); emit StreamCreated(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); } diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index c40fbeb..b7105a0 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -57,7 +57,7 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "deposit: No role"); require(isSupportedToken[_token], "Unsupported token"); deposited[_token] += _amount; - IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount); + IERC20(_token).safeTransferFrom(_user, address(this), _amount); } /// @notice adds token as a supproted rewards token by Vault From c691ec511efe12718c32a6f8ec62632f17472035 Mon Sep 17 00:00:00 2001 From: ssubik Date: Tue, 24 Jan 2023 11:37:49 +0545 Subject: [PATCH 27/77] doing audit fixes --- contracts/common/SafeERC20Staking.sol | 68 +++++++ .../staking/helpers/IStakingGetterHelper.sol | 32 +-- .../staking/helpers/StakingGettersHelper.sol | 187 +++++++++--------- .../dao/staking/interfaces/IStakingEvents.sol | 2 +- .../dao/staking/interfaces/IStakingGetter.sol | 15 +- .../dao/staking/packages/StakingGetters.sol | 11 +- .../dao/staking/packages/StakingHandler.sol | 40 ++-- .../dao/staking/vault/interfaces/IVault.sol | 1 - .../staking/vault/packages/VaultPackage.sol | 5 +- scripts/migrations/test/6_init_main_stream.js | 2 +- scripts/tests/dao/demo/staking.demo.test.js | 2 +- scripts/tests/dao/staking/staking.test.js | 16 +- 12 files changed, 223 insertions(+), 158 deletions(-) create mode 100644 contracts/common/SafeERC20Staking.sol diff --git a/contracts/common/SafeERC20Staking.sol b/contracts/common/SafeERC20Staking.sol new file mode 100644 index 0000000..323a5ca --- /dev/null +++ b/contracts/common/SafeERC20Staking.sol @@ -0,0 +1,68 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) + +pragma solidity 0.8.13; + +import "../dao/tokens/ERC20/IERC20.sol"; +import "../dao/tokens/ERC20/extensions/IERC20Permit.sol"; +import "./Address.sol"; + +/** + * @title SafeERC20 + * @dev Wrappers around ERC20 operations that throw on failure (when the token + * contract returns false). Tokens that return no value (and instead revert or + * throw on failure) are also supported, non-reverting calls are assumed to be + * successful. + * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, + * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. + */ +library SafeERC20Staking { + using Address for address; + + function safeTransferFrom( + IERC20 token, + address from, + address to, + uint256 value + ) internal { + _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); + } + + /** + * @dev Deprecated. This function has issues similar to the ones found in + * {IERC20-approve}, and its usage is discouraged. + * + * Whenever possible, use {safeIncreaseAllowance} and + * {safeDecreaseAllowance} instead. + */ + function safeApprove( + IERC20 token, + address spender, + uint256 value + ) internal { + // safeApprove should only be called when setting an initial allowance, + // or when resetting it to zero. To increase and decrease it, use + // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' + require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance"); + _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); + } + + + /** + * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement + * on the return value: the return value is optional (but if data is returned, it must not be false). + * @param token The token targeted by the call. + * @param data The call data (encoded using abi.encode or one of its variants). + */ + function _callOptionalReturn(IERC20 token, bytes memory data) private { + // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since + // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that + // the target address contains contract code and also asserts for success in the low-level call. + + bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); + if (returndata.length > 0) { + // Return data is optional + require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); + } + } +} diff --git a/contracts/dao/staking/helpers/IStakingGetterHelper.sol b/contracts/dao/staking/helpers/IStakingGetterHelper.sol index 1708244..dce197e 100644 --- a/contracts/dao/staking/helpers/IStakingGetterHelper.sol +++ b/contracts/dao/staking/helpers/IStakingGetterHelper.sol @@ -9,26 +9,26 @@ import "../interfaces/IStakingStorage.sol"; import "../../../common/security/IAdminPausable.sol"; interface IStakingGetterHelper { - // function getLockInfo(address account, uint256 lockId) external view returns (LockedBalance memory); + function getLockInfo(address account, uint256 lockId) external view returns (LockedBalance memory); - // function getLock(address account, uint256 lockId) - // external - // view - // returns ( - // uint128, - // uint128, - // uint128, - // uint64, - // address - // ); + function getLock(address account, uint256 lockId) + external + view + returns ( + uint128, + uint128, + uint128, + uint64, + address + ); - // function getUserTotalDeposit(address account) external view returns (uint256); + function getUserTotalDeposit(address account) external view returns (uint256); - // function getStreamClaimableAmount(uint256 streamId, address account) external view returns (uint256); + function getStreamClaimableAmount(uint256 streamId, address account) external view returns (uint256); - // function getUserTotalVotes(address account) external view returns (uint256); + function getUserTotalVotes(address account) external view returns (uint256); - // function getFeesForEarlyUnlock(uint256 lockId, address account) external view returns (uint256); + function getFeesForEarlyUnlock(uint256 lockId, address account) external view returns (uint256); - // function getLocksLength(address account) external view returns (uint256); + function getLocksLength(address account) external view returns (uint256); } diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index 1a9fdac..8299a6d 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -13,95 +13,95 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { uint256 internal constant ONE_YEAR = 31536000; uint256 internal constant WEEK = 604800; uint256 public constant WEIGHT_SLOT = 14; - // constructor(address _stakingContract, address admin) { - // stakingContract = _stakingContract; - // _grantRole(DEFAULT_ADMIN_ROLE, admin); - // } + constructor(address _stakingContract, address admin) { + stakingContract = _stakingContract; + _grantRole(DEFAULT_ADMIN_ROLE, admin); + } - // function getLockInfo(address account, uint256 lockId) public view override returns (LockedBalance memory) { - // LockedBalance[] memory locks = _getAllLocks(account); - // require(lockId <= locks.length, "out of index"); - // require(lockId > 0, "lockId cant be 0"); - // return locks[lockId - 1]; - // } + function getLockInfo(address account, uint256 lockId) public view override returns (LockedBalance memory) { + LockedBalance[] memory locks = _getAllLocks(account); + require(lockId <= locks.length, "out of index"); + require(lockId > 0, "lockId cant be 0"); + return locks[lockId - 1]; + } - // function getLocksLength(address account) public view override returns (uint256) { - // LockedBalance[] memory locks = _getAllLocks(account); - // return locks.length; - // } + function getLocksLength(address account) public view override returns (uint256) { + LockedBalance[] memory locks = _getAllLocks(account); + return locks.length; + } - // function getLock(address account, uint256 lockId) - // public - // view - // override - // returns ( - // uint128, - // uint128, - // uint128, - // uint64, - // address - // ) - // { - // LockedBalance[] memory locks = _getAllLocks(account); - // LockedBalance memory lock = locks[lockId - 1]; - // require(lockId <= locks.length, "out of index"); - // require(lockId > 0, "lockId cant be 0"); - // return (lock.amountOfToken, lock.amountOfVoteToken, lock.positionStreamShares, lock.end, lock.owner); - // } + function getLock(address account, uint256 lockId) + public + view + override + returns ( + uint128, + uint128, + uint128, + uint64, + address + ) + { + LockedBalance[] memory locks = _getAllLocks(account); + LockedBalance memory lock = locks[lockId - 1]; + require(lockId <= locks.length, "out of index"); + require(lockId > 0, "lockId cant be 0"); + return (lock.amountOfToken, lock.amountOfVoteToken, lock.positionStreamShares, lock.end, lock.owner); + } - // function getUserTotalDeposit(address account) public view override returns (uint256) { - // LockedBalance[] memory locks = _getAllLocks(account); - // if (locks.length == 0) { - // return 0; - // } - // uint256 totalDeposit = 0; - // for (uint256 lockId = 1; lockId <= locks.length; lockId++) { - // totalDeposit += locks[lockId - 1].amountOfToken; - // } - // return totalDeposit; - // } + function getUserTotalDeposit(address account) public view override returns (uint256) { + LockedBalance[] memory locks = _getAllLocks(account); + if (locks.length == 0) { + return 0; + } + uint256 totalDeposit = 0; + for (uint256 lockId = 1; lockId <= locks.length; lockId++) { + totalDeposit += locks[lockId - 1].amountOfToken; + } + return totalDeposit; + } - // function getStreamClaimableAmount(uint256 streamId, address account) public view override returns (uint256) { - // LockedBalance[] memory locks = _getAllLocks(account); - // if (locks.length == 0) { - // return 0; - // } - // uint256 totalRewards = 0; - // for (uint256 lockId = 1; lockId <= locks.length; lockId++) { - // totalRewards += IStakingHelper(stakingContract).getStreamClaimableAmountPerLock(streamId, account, lockId); - // } - // return totalRewards; - // } + function getStreamClaimableAmount(uint256 streamId, address account) public view override returns (uint256) { + LockedBalance[] memory locks = _getAllLocks(account); + if (locks.length == 0) { + return 0; + } + uint256 totalRewards = 0; + for (uint256 lockId = 1; lockId <= locks.length; lockId++) { + totalRewards += IStakingHelper(stakingContract).getStreamClaimableAmountPerLock(streamId, account, lockId); + } + return totalRewards; + } - // function getUserTotalVotes(address account) public view override returns (uint256) { - // LockedBalance[] memory locks = _getAllLocks(account); - // if (locks.length == 0) { - // return 0; - // } - // uint256 totalVotes = 0; - // for (uint256 lockId = 1; lockId <= locks.length; lockId++) { - // totalVotes += locks[lockId - 1].amountOfVoteToken; - // } - // return totalVotes; - // } + function getUserTotalVotes(address account) public view override returns (uint256) { + LockedBalance[] memory locks = _getAllLocks(account); + if (locks.length == 0) { + return 0; + } + uint256 totalVotes = 0; + for (uint256 lockId = 1; lockId <= locks.length; lockId++) { + totalVotes += locks[lockId - 1].amountOfVoteToken; + } + return totalVotes; + } - // function getFeesForEarlyUnlock(uint256 lockId, address account) public view override returns (uint256) { - // LockedBalance[] memory locks = _getAllLocks(account); - // require(lockId <= locks.length, "out of index"); - // LockedBalance memory lock = locks[lockId - 1]; - // require(lockId > 0, "lockId cant be 0"); - // require(lock.end > block.timestamp, "lock opened, no penalty"); + function getFeesForEarlyUnlock(uint256 lockId, address account) public view override returns (uint256) { + LockedBalance[] memory locks = _getAllLocks(account); + require(lockId <= locks.length, "out of index"); + LockedBalance memory lock = locks[lockId - 1]; + require(lockId > 0, "lockId cant be 0"); + require(lock.end > block.timestamp, "lock opened, no penalty"); - // uint256 amount = lock.amountOfToken; - // uint256 lockEnd = lock.end; - // uint256 weighingCoef = _weightedPenalty(lockEnd, block.timestamp); - // uint256 penalty = (weighingCoef * amount) / 100000; - // return penalty; - // } + uint256 amount = lock.amountOfToken; + uint256 lockEnd = lock.end; + uint256 weighingCoef = _weightedPenalty(lockEnd, block.timestamp); + uint256 penalty = (weighingCoef * amount) / 100000; + return penalty; + } - function _getAllLocks(address account) internal view returns (LockedBalance[] memory) { - - } + function _getAllLocks(address account) internal view returns(LockedBalance[] memory) { + return IStakingHelper(stakingContract).getAllLocks(account); + } function _weightedPenalty(uint256 lockEnd, uint256 timestamp) internal view returns (uint256) { Weight memory weight = _getWeight(); @@ -118,7 +118,7 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { maxLockPeriod); } - function _getWeight() internal view returns (Weight memory returnWeight) { + function _getWeight() internal view returns (Weight memory) { bytes32 weight = IStakingHelper(stakingContract).readBySlot(WEIGHT_SLOT); uint32 penaltyWeightMultiplier; uint32 minWeightPenalty; @@ -127,23 +127,22 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { uint32 maxWeightShares; assembly { let value := weight - let shifted := shr(96,value) - penaltyWeightMultiplier := and(0xffff, shifted) - shifted := shr(128,value) - minWeightPenalty := and(0xffff, shifted) - shifted := shr(160,value) - maxWeightPenalty := and(0xffff, shifted) - shifted := shr(192,value) - minWeightShares := and(0xffff, shifted) - shifted := shr(224,value) - maxWeightShares := and(0xffff, shifted) + maxWeightShares := and(0xffff, value) + let shifted_2 := shr(32,value) + minWeightShares := and(0xffff, shifted_2) + let shifted_3 := shr(64,value) + maxWeightPenalty := and(0xffff, shifted_3) + let shifted_4 := shr(96,value) + minWeightPenalty := and(0xffff, shifted_4) + let shifted_5 := shr(128,value) + penaltyWeightMultiplier := and(0xffff, shifted_5) } return Weight( - minWeightPenalty, - maxWeightPenalty, - minWeightShares, maxWeightShares, + minWeightShares, + maxWeightPenalty, + minWeightPenalty, penaltyWeightMultiplier ); } diff --git a/contracts/dao/staking/interfaces/IStakingEvents.sol b/contracts/dao/staking/interfaces/IStakingEvents.sol index df96d1b..d1ad4cc 100644 --- a/contracts/dao/staking/interfaces/IStakingEvents.sol +++ b/contracts/dao/staking/interfaces/IStakingEvents.sol @@ -9,7 +9,7 @@ interface IStakingEvents { event StreamProposed(uint256 indexed streamId, address indexed streamOwner, address indexed rewardToken, uint256 maxDepositAmount); event Released(uint256 indexed streamId, address indexed user, uint256 pendingAmount); event StreamProposalCancelled(uint256 indexed streamId, address indexed owner, address indexed token); - event StreamCreated(uint256 indexed streamId, address indexed owner, address indexed token, uint256 tokenAmount); + event StreamCreated(uint256 indexed streamId, address indexed owner, address indexed token, uint256[] scheduleRewards, uint256[] scheduleTimes); event StreamRemoved(uint256 indexed streamId, address indexed owner, address indexed token); event Unstaked(address indexed account, uint256 amount, uint256 indexed lockId); event PartialUnstaked(address indexed account, uint256 amount, uint256 indexed lockId); diff --git a/contracts/dao/staking/interfaces/IStakingGetter.sol b/contracts/dao/staking/interfaces/IStakingGetter.sol index b03cdf5..418948f 100644 --- a/contracts/dao/staking/interfaces/IStakingGetter.sol +++ b/contracts/dao/staking/interfaces/IStakingGetter.sol @@ -23,17 +23,14 @@ interface IStakingGetter { // ); function getAllLocks(address account) external view returns (LockedBalance[] memory); - + function getUsersPendingRewards(address account, uint256 streamId) external view returns (uint256); function getStreamClaimableAmountPerLock( - uint256 streamId, - address account, - uint256 lockId - ) external view returns (uint256); - + uint256 streamId, + address account, + uint256 lockId + ) external view returns (uint256); function readBySlot(uint256 slot) external view returns(bytes32); - function getAddressToList(uint256 slot,uint256 index, address account) external view returns(bytes memory value); - -// function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); + //function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); // function getStreamsCount() external view returns (uint256); diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index 7d5cb00..3c50181 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -9,7 +9,9 @@ import "../interfaces/IStakingGetter.sol"; import "./StakingInternals.sol"; contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { - + function getUsersPendingRewards(address account, uint256 streamId) external view override returns (uint256) { + return users[account].pendings[streamId]; + } function getStreamClaimableAmountPerLock( uint256 streamId, address account, @@ -31,11 +33,8 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { } } - function getAddressToList(uint256 slot,uint256 index, address account) external view override returns(bytes memory value){ - bytes32 location = keccak256(abi.encode(keccak256(abi.encode(account, slot)))); - assembly { - value := sload(add(location,index)) - } + function getAllLocks(address account) external view returns (LockedBalance[] memory) { + return locks[account]; } // function getStream(uint256 streamId) diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index db28230..c51bc84 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -9,11 +9,11 @@ import "../StakingStorage.sol"; import "../interfaces/IStakingHandler.sol"; import "../vault/interfaces/IVault.sol"; import "../../../common/security/AdminPausable.sol"; -import "../../../common/SafeERC20.sol"; +import "../../../common/SafeERC20Staking.sol"; // solhint-disable not-rely-on-time contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, AdminPausable { - using SafeERC20 for address; + using SafeERC20Staking for IERC20; bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); @@ -44,7 +44,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A ) external override initializer { rewardsCalculator = _rewardsContract; _initializeStaking(_mainToken, _voteToken, _weight, _vault, _maxLocks, voteCoef.voteShareCoef, voteCoef.voteLockCoef); - require(IVault(vault).isSupportedToken(_mainToken), "Unsupported token"); + require(IVault(vault).isSupportedToken(_mainToken), "!token"); pausableInit(1, _admin); _grantRole(STREAM_MANAGER_ROLE, _admin); _grantRole(TREASURY_ROLE, _admin); @@ -77,12 +77,10 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A }) ); _adminPause(0); - IVault(vault).deposit(msg.sender, mainToken, scheduleRewards[0]); mainStreamInitialized =true; - - + _transfer(scheduleRewards[0],mainToken); emit StreamProposed(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); - emit StreamCreated(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); + emit StreamCreated(streamId, _owner, mainToken, scheduleRewards,scheduleTimes); } /** @@ -112,7 +110,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A uint256 tau ) public override onlyRole(STREAM_MANAGER_ROLE) { _validateStreamParameters(streamOwner, rewardToken, maxDepositAmount, minDepositAmount, scheduleTimes, scheduleRewards, tau); - require(IVault(vault).isSupportedToken(rewardToken), "Unsupport Token"); + require(IVault(vault).isSupportedToken(rewardToken), "!Token"); Schedule memory schedule = Schedule(scheduleTimes, scheduleRewards); uint256 streamId = streams.length; streams.push( @@ -135,7 +133,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function createStream(uint256 streamId, uint256 rewardTokenAmount) public override pausable(1) { Stream storage stream = streams[streamId]; - require(stream.status == StreamStatus.PROPOSED, "not proposed"); + require(stream.status == StreamStatus.PROPOSED, "nt proposed"); require(stream.schedule.time[0] >= block.timestamp, "prop expire"); require(stream.owner == msg.sender, "bad owner"); @@ -150,13 +148,13 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } require(stream.schedule.reward[0] == stream.rewardDepositAmount, "bad start"); - emit StreamCreated(streamId, stream.owner, stream.rewardToken, rewardTokenAmount); - IVault(vault).deposit(msg.sender, stream.rewardToken, rewardTokenAmount); + emit StreamCreated(streamId, stream.owner, stream.rewardToken,stream.schedule.time, stream.schedule.reward); + _transfer(rewardTokenAmount,stream.rewardToken); } function cancelStreamProposal(uint256 streamId) public override onlyRole(STREAM_MANAGER_ROLE) { Stream storage stream = streams[streamId]; - require(stream.status == StreamStatus.PROPOSED, "not proposed"); + require(stream.status == StreamStatus.PROPOSED, "nt proposed"); stream.status = StreamStatus.INACTIVE; emit StreamProposalCancelled(streamId, stream.owner, stream.rewardToken); @@ -180,7 +178,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } function createLocksForCouncils(CreateLockParams[] calldata lockParams) public override onlyRole(DEFAULT_ADMIN_ROLE) { - require(!councilsInitialized, "already created"); + require(!councilsInitialized, "created"); councilsInitialized = true; for (uint256 i = 0; i < lockParams.length; i++) { address account = lockParams[i].account; @@ -196,7 +194,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function unlock(uint256 lockId) public override pausable(1) { _verifyUnlock(lockId); LockedBalance storage lock = locks[msg.sender][lockId - 1]; - require(lock.end <= block.timestamp, "lock not open"); + require(lock.end <= block.timestamp, "lock close"); _updateStreamRPS(); uint256 stakeValue = lock.amountOfToken; _unlock(stakeValue, stakeValue, lockId, msg.sender); @@ -206,7 +204,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function unlockPartially(uint256 lockId, uint256 amount) public override pausable(1) { _verifyUnlock(lockId); LockedBalance storage lock = locks[msg.sender][lockId - 1]; - require(lock.end <= block.timestamp, "lock not open"); + require(lock.end <= block.timestamp, "lock close"); _updateStreamRPS(); uint256 stakeValue = lock.amountOfToken; _unlock(stakeValue, amount, lockId, msg.sender); @@ -217,14 +215,14 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _verifyUnlock(lockId); require(prohibitedEarlyWithdraw[msg.sender][lockId] == false, "early infeasible"); LockedBalance storage lock = locks[msg.sender][lockId - 1]; - require(lock.end > block.timestamp, "lock opened"); + require(lock.end > block.timestamp, "lock open"); _updateStreamRPS(); _earlyUnlock(lockId, msg.sender); } function claimAllStreamRewardsForLock(uint256 lockId) public override pausable(1) { require(lockId <= locks[msg.sender].length, "bad lockid"); - require(lockId != 0, "lockId zero"); + require(lockId != 0, "lockId 0"); _updateStreamRPS(); // Claim all streams while skipping inactive streams. _moveAllStreamRewardsToPending(msg.sender, lockId); @@ -290,7 +288,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A require(lockPeriod <= maxLockPeriod, "max time"); _updateStreamRPS(); _lock(account, amount, lockPeriod); - IVault(vault).deposit(msg.sender, mainToken, amount); + _transfer(amount,mainToken); } function _verifyUnlock(uint256 lockId) internal view { @@ -300,4 +298,10 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A require(lock.amountOfToken > 0, "no amount"); require(lock.owner == msg.sender, "bad owner"); } + + function _transfer(uint256 _amount, address _token) internal { + IERC20(_token).safeTransferFrom(msg.sender,address(this),_amount); + IERC20(_token).safeApprove(vault,_amount); + IVault(vault).deposit(_token, _amount); + } } diff --git a/contracts/dao/staking/vault/interfaces/IVault.sol b/contracts/dao/staking/vault/interfaces/IVault.sol index 122a720..84201d6 100644 --- a/contracts/dao/staking/vault/interfaces/IVault.sol +++ b/contracts/dao/staking/vault/interfaces/IVault.sol @@ -5,7 +5,6 @@ interface IVault { function initVault(address _admin, address[] calldata supportedTokens) external; function deposit( - address _user, address _token, uint256 _amount ) external; diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index b7105a0..cbc8bfe 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -50,14 +50,13 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { } function deposit( - address _user, address _token, uint256 _amount ) external override pausable(1) { require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "deposit: No role"); require(isSupportedToken[_token], "Unsupported token"); deposited[_token] += _amount; - IERC20(_token).safeTransferFrom(_user, address(this), _amount); + IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount); } /// @notice adds token as a supproted rewards token by Vault @@ -101,7 +100,7 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { address token = listOfSupportedTokens[i]; deposited[token] = 0; IERC20(token).safeApprove(newVaultPackage, deposited[token]); - IVault(newVaultPackage).deposit(address(this),listOfSupportedTokens[i], deposited[token]); + IVault(newVaultPackage).deposit(listOfSupportedTokens[i], deposited[token]); } migrated = true; } diff --git a/scripts/migrations/test/6_init_main_stream.js b/scripts/migrations/test/6_init_main_stream.js index 0a56c74..17dbcd4 100644 --- a/scripts/migrations/test/6_init_main_stream.js +++ b/scripts/migrations/test/6_init_main_stream.js @@ -82,7 +82,7 @@ module.exports = async function(deployer) { let resultApprove = await multiSigWallet.submitTransaction( MainToken.address, EMPTY_BYTES, - _encodeApproveFunction(VaultProxy.address,scheduleRewards[0]), + _encodeApproveFunction(StakingProxy.address,scheduleRewards[0]), 0, {gas: 8000000} ) diff --git a/scripts/tests/dao/demo/staking.demo.test.js b/scripts/tests/dao/demo/staking.demo.test.js index ba026d7..7b50d5d 100644 --- a/scripts/tests/dao/demo/staking.demo.test.js +++ b/scripts/tests/dao/demo/staking.demo.test.js @@ -405,7 +405,7 @@ describe("Staking Test and Upgrade Test", () => { it("Should not unlock locked position before the end of the lock position's lock period - staker_1", async() => { - const errorMessage = "lock not open"; + const errorMessage = "lock close"; await shouldRevert( stakingService.unlock(1, {from: staker_1}), diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index f952ca0..e7586b7 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -347,7 +347,7 @@ describe("Staking Test", () => { expectedTotalAmountOfVFTHM = new web3.utils.BN(0) it('Should create a lock possition with lockId = 1 for staker_1', async() => { // So that staker 1 can actually stake the token: - await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_1}) + await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_1}) const beforeFTHMBalance = await FTHMToken.balanceOf(staker_1); await blockchain.increaseTime(20); @@ -416,9 +416,9 @@ describe("Staking Test", () => { const sumToDepositForAll = web3.utils.toWei('100', 'ether'); - await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_2}) - await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_3}) - await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_4}) + await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_2}) + await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_3}) + await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_4}) await blockchain.mineBlock(await _getTimeStamp() + 20); @@ -441,7 +441,7 @@ describe("Staking Test", () => { it("Should not unlock locked position before the end of the lock possition's lock period - staker_1", async() => { - const errorMessage = "lock not open"; + const errorMessage = "lock close"; await shouldRevert( stakingService.unlock(1, {from: staker_1}), @@ -648,7 +648,7 @@ describe("Staking Test", () => { it("Should Create a Stream", async() => { // Once createStream is called, the proposal will become live once start time is reached const RewardProposalAmountForAStream = web3.utils.toWei('800', 'ether'); - await streamReward1.approve(vaultService.address, RewardProposalAmountForAStream, {from:stream_rewarder_1}) + await streamReward1.approve(stakingService.address, RewardProposalAmountForAStream, {from:stream_rewarder_1}) await stakingService.createStream(1,RewardProposalAmountForAStream, {from: stream_rewarder_1}); await blockchain.mineBlock(await _getTimeStamp() + 20); }) @@ -716,7 +716,7 @@ describe("Staking Test", () => { it("Should Create a Stream - 2", async() => { const RewardProposalAmountForAStream = web3.utils.toWei('1000', 'ether'); - await streamReward2.approve(vaultService.address, RewardProposalAmountForAStream, {from:stream_rewarder_2}) + await streamReward2.approve(stakingService.address, RewardProposalAmountForAStream, {from:stream_rewarder_2}) await stakingService.createStream(2,RewardProposalAmountForAStream, {from: stream_rewarder_2}); }) @@ -1129,7 +1129,7 @@ describe("Staking Test", () => { const sumToApprove = web3.utils.toWei('20000','ether'); - await FTHMToken.approve(vaultService.address, sumToApprove, {from: accounts[9]}) + await FTHMToken.approve(stakingService.address, sumToApprove, {from: accounts[9]}) const lockingPeriod = 365 * 24 * 60 * 60 const unlockTime = lockingPeriod; From c10cb49cac3ea0cc50e8536854d6b6295ce68c1b Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 25 Jan 2023 15:00:12 +0545 Subject: [PATCH 28/77] working on audits --- audit-report/Fathom_DAO-review.md | 46 +++--- contracts/dao/governance/Governor.sol | 27 +++- contracts/dao/governance/GovernorStructs.sol | 1 + .../dao/governance/MainTokenGovernor.sol | 15 +- .../dao/governance/TimelockController.sol | 22 ++- .../extensions/GovernorTimelockControl.sol | 2 +- .../staking/helpers/IStakingGetterHelper.sol | 1 + .../staking/helpers/StakingGettersHelper.sol | 22 ++- .../dao/staking/library/RewardsLibrary.sol | 1 - .../dao/staking/packages/StakingGetters.sol | 5 +- .../dao/staking/packages/StakingHandler.sol | 1 + .../dao/staking/packages/StakingInternals.sol | 5 +- .../staking/vault/packages/VaultPackage.sol | 4 - contracts/dao/tokens/VMainToken.sol | 1 - contracts/dao/treasury/MultiSigWallet.sol | 45 +++--- .../treasury/interfaces/IMultiSigWallet.sol | 2 +- .../deployment/5_deploy_governor.js | 4 + scripts/tests/dao/demo/staking.demo.test.js | 8 +- scripts/tests/dao/full-flow-demo.test.js | 68 ++++---- .../dao/governance/proposal-flow.test.js | 148 +++++++++--------- .../token-creation-though-gov.test.js | 44 +++--- 21 files changed, 268 insertions(+), 204 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 89e4fbb..406103a 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -101,7 +101,7 @@ The reaudited commit identifier with implemented Oxorio's recommendations is [`d ### CRITICAL -#### 1. [NEW] There's no `owners` array length validation in the constructor of `MultiSigWallet`[DONE] +#### [NEW] There's no `owners` array length validation in the constructor of `MultiSigWallet`[DONE] ##### Description In the [MultiSigWallet\`s constructor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L76) there's no checking that the number of `owners` is less than or equal `MAX_OWNER_COUNT`. If the contract is created with `owners` with length more than `MAX_OWNER_COUNT` then that makes calls to `addOwner`, `changeRequirement` and `removeOwner` (which uses call `changeRequirement`) functions impossible because they use modifier `validRequirement` with this `require` statement: ```solidity @@ -143,7 +143,7 @@ Implemented Auditors Recommendation. with slight change: changeRequirement(numConfirmationsRequired + _owners.length); ``` -#### 2. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE] +#### 1. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE -ASK MAXJI - ask auditor, does it require to revoke confirmation in submitTransaction] ##### Description In the function [`removeOwner`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L96) the owner is being removed without revocation of transaction signatures, where they've signed. This creates a situation where the signatures of non-existent owners may be used. For example, like in the following scenario: @@ -180,7 +180,7 @@ We recommend adding logic that would allow you to cancel the execution of `propo ###### Fathom's response Implemented Auditors Recommendation. -#### 3. [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE] +#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE] ##### Description A change of the `timelock` parameter in the [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L22) contract can lead to already executed `proposals` being able to be executed again. This is connected to the fact that the execution status of the transaction is saved only in the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, and the `GovernorTimelockControl` contract makes calls to the `TimelockController` functions to get the `proposals` status in the [`state`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L50) function. ##### Recommendation @@ -256,8 +256,8 @@ modifier validRequirement(uint ownerCount, uint _required) { } ``` -#### 4. [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet` -##### Description[NOTDONE] +#### 2. [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet` +##### Description[NOTDONE - CHECKAGAIN -ASK MAXJI] In the structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) there's no lifetime parameter `expired`, which is responsible for the period of time during which the transaction must be executed. Since transactions may be executed at random time and are not removed over time, frozen, previously not approved transactions can be executed after a certain time and cause an undesirable effect. ##### Recommendation We recommend adding an individual parameter, which is responsible for the maximum time until the transaction can be executed, e.g. `expired` and check it before running transactions. @@ -272,7 +272,7 @@ We meant the `lifetime` parameter, which is passed as a function parameter. `transactions[_txIndex].expireTimestamp = block.timestamp + lifetime` -#### 5. [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[NOTDONE] +#### 5. [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[DONE] ##### Description In the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, Governance can take away the `TIMELOCK_ADMIN_ROLE` rights from the address `admin`. In the case of an attack on `Governance` and `Council` this would make it impossible to revoke the role from the captured contracts. ##### Recommendation @@ -303,7 +303,7 @@ We recommend adding the `updateMultisig` function, but so that only the old `mul ###### Fathom's response Implemented Auditors Recommendation. -#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE] +#### 6. [NEW] There is no emergency shutdown mode in `Governor`[DONE] ##### Description There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. ##### Recommendation @@ -346,7 +346,7 @@ We recommend adding a constant with the minimum allowable value of `_quorumNumer Implemented Auditors Recommendation. -#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE] +#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update ##### Description In the [VMainToken](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) contract, for mint tokens, calling account, in addition to having `MINTER_ROLE` rights, must also be in the `isWhiteListed` list, since the mint function calls `_mint,` which contains [`_beforeTokenTransfer`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65) call. When `_beforeTokenTransfer` is called, it checks that the `msg.sender` address is in the `isWhiteListed` list. @@ -394,7 +394,7 @@ But it should be noted that `addToWhitelist` and `removeFromWhitelist` can be ca We recommend refactoring this code and adding internal functions `_addToWhitelist` and `_removeFromWhitelist` without access control to `grantMinterRole` and `revokeMinterRole`. -#### 8. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[NOTDONE-CHECK] +#### 3. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[NOTDONE-CHECK] ##### Description In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. ##### Recommendation @@ -419,7 +419,7 @@ We recommend making two different functions for relaying `ERC20` tokens and nati -#### 9. [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE] +#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE] ##### Description The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol) contract lacks the ability to suspend a contract in an emergency and migrate assets to a new compatible `VaultPackage` contract. @@ -438,7 +438,7 @@ We recommend forbidding to use functions after migration. We recommend using `deposited` variable instead `balanceOf` `VaultPackage` balance. -#### 10. [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE] +#### 4. [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE-> Do at last] ##### Description In the `StakingHandlers` contract, calling the function [`updateVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L269) can cause all contract functions that work with balances and `VaultPackage` functions to be blocked. ##### Recommendation @@ -485,7 +485,7 @@ We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppeli ###### Fathom's response Implemented Auditors Recommendation. -#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE-CHECK] +#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE-AskAnton] ##### Description In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. @@ -563,7 +563,7 @@ bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); ###### Fathom's response Implemented Auditors Recommendation. -#### 13. [NEW] Transaction should be marked as `executed` if the call fails[NOTDONE] +#### 5. [NEW] Transaction should be marked as `executed` if the call fails[NOTDONE -> CHECKAGAIN MAXJI!! Makes sense?] ##### Description @@ -622,7 +622,7 @@ We recommend: ###### Fathom's response Implemented Auditors Recommendation. -#### 14 .[NEW] `prohibitedEarlyWithdraw` is not set to `false` for `lockid` after unlocking in `StakingHandlers` +#### 14 .[NEW] `prohibitedEarlyWithdraw` is not set to `false` for `lockid` after unlocking in `StakingHandlers`[DONE] ##### Description In the function [`createLockWithoutEarlyWithdraw`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L181) in the `StakingHandlers` contract parameter `prohibitedEarlyWithdraw` for given `lockid` is set to `true`, but it does not update to `false` after unlocking later in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions. Since the value in the `locks` array is deleted after the unlock, all new values will be assigned the value of `prohibitedEarlyWithdraw`, regardless of whether the `createLockWithoutEarlyWithdraw` or `createLock` function is called. @@ -779,7 +779,7 @@ We recommend removing `Governance` from this modifier and give the permission to ###### Fathom's response Thats the way its designed -#### 16. [NEW] No parameter check when adding transaction in `MultiSigWallet`[NOTDONE] +#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[NOTDONE -CHECK AGAIN] ##### Description In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. Based on the logic of the contract, there may be the following cases: @@ -843,7 +843,7 @@ In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom- ##### Recommendation We recommend adding balance check while adding a transaction with a non-zero value `_value`. -#### [NEW] There is no time limit for executing proposal in `Governor` +#### [NEW] There is no time limit for executing proposal in `Governor`[Ask MAXJI -DONE] ##### Description The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract has no parameters for the time limit on `proposal` execution. This can result in no longer relevant proposal being executed after a period of time. ##### Recommendation @@ -879,7 +879,7 @@ require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Go ###### Fathom's response Implemented Auditors Recommendation. -#### 17. [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController` +#### 17. [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[DONE Check again] ##### Description In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) contracts the `execute` functions do not check the `msg.value` balance value needed to execute `_targets`, which would result in gas consumption even if the amount of `ETH` is not enough. ##### Recommendation @@ -915,7 +915,7 @@ We recommend adding a check that `newProposalThreshold` is not zero. ###### Fathom's response Implemented Auditors Recommendation. -#### 18. [NEW] There is no limit on the number of proposals for one proposer in `Governor` +#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE: Keep an array of proposals and loop? Ask MAXJI -ASK AUDITOR] ##### Description In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. ##### Recommendation @@ -928,6 +928,8 @@ The implemented fix does not fully resolve the problem. The Proposer can still create an unlimited number of proposals. We recommend adding a limit for pending proposals for one user. +Ask Auditors -> This is not desired functionality to limit pending proposals for one user. + #### [FIXED] A missing check that tokens are on the balance when calling the `payRewards` function in the `VaultPackage` contract ##### Description In the `VaultPackage` contract when calling the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31) there is no processing of errors such as: @@ -976,7 +978,7 @@ We recommend adding a condition that `createStream` can only be called from the ###### Fathom's response Implemented Auditors Recommendation. -#### 19. [NEW] Possible overflow with calculations +#### 8. [NEW] Possible overflow with calculations[NOTDONE] ##### Description In the next lines there is a possible overflow: @@ -1049,7 +1051,7 @@ Implemented Auditors Recommendation. ### INFO -#### 20. [NEW] There's no logging of reverted transactions in `MultiSigWallet` +#### 20. [NEW] There's no logging of reverted transactions in `MultiSigWallet`[DONE] ##### Description In the function [`executeConfirmation`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L144) there's no logging of failed transactions. ```solidity @@ -1305,7 +1307,7 @@ We recommend removing `'` from the comment. Implemented Auditors Recommendation. -#### [NEW] There is a typo in a comment in `StakingInternals` +#### [NEW] There is a typo in a comment in `StakingInternals`[DONE] ##### Description @@ -1388,7 +1390,7 @@ We recommend removing the unused import. ###### Fathom's response Implemented Auditors Recommendation. -#### [NEW] Сustom `initializer` modifier is used instead of one from OpenZeppelin +#### [NEW] Сustom `initializer` modifier is used instead of one from OpenZeppelin[DONE] ##### Description diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index e00ed8a..ef13df1 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -28,6 +28,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { event MultiSigUpdated(address newMultiSig, address oldMultiSig); event MaxTargetUpdated(uint256 newMaxTargets, uint256 oldMaxTargets); event ProposalTimeDelayUpdated(uint256 newProposalTimeDelay, uint256 oldProposalTimeDelay); + event ExecuteTransaction(address indexed owner, bool success, bytes data); bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); @@ -37,6 +38,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { uint256[] private proposalIds; address private multiSig; + uint256 public proposalLifetime; mapping(uint256 => ProposalCore) internal _proposals; mapping(uint256 => string) internal _descriptions; @@ -44,7 +46,8 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { mapping(address => uint256) public nextAcceptableProposalTimestamp; DoubleEndedQueue.Bytes32Deque private _governanceCall; - + uint256 public constant MINIMUM_LIFETIME = 86400;//oneDay + modifier onlyGovernance() { require(_msgSender() == _executor(), "Governor: onlyGovernance"); if (_executor() != address(this)) { @@ -74,15 +77,19 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { string memory name_, address multiSig_, uint256 maxTargets_, - uint256 proposalTimeDelay_ + uint256 proposalTimeDelay_, + uint256 proposalLifetime_ ) EIP712(name_, version()) { require(multiSig_ != address(0), "multiSig address cant be zero address"); require(maxTargets_ != 0, "maxTarget cant be zero"); require(proposalTimeDelay_ != 0, "proposalTimeDelay cant be zero"); + require(proposalLifetime_ >= MINIMUM_LIFETIME,"lifetime less than minimum"); _name = name_; multiSig = multiSig_; maxTargets = maxTargets_; proposalTimeDelay = proposalTimeDelay_; + //TODO Updateable + proposalLifetime = proposalLifetime_; } receive() external payable virtual { @@ -96,6 +103,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { bytes32 descriptionHash ) public payable virtual override whenNotPaused returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); + requireNotExpired(proposalId); requireConfirmed(proposalId); ProposalState status = state(proposalId); @@ -200,6 +208,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { proposal.voteStart.setDeadline(snapshot); proposal.voteEnd.setDeadline(deadline); + proposal.expireTimestamp = block.timestamp + proposalLifetime; _descriptions[proposalId] = description; proposalIds.push(proposalId); @@ -210,6 +219,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { } function confirmProposal(uint256 _proposalId) public onlyMultiSig notExecuted(_proposalId) notConfirmed(_proposalId) { + requireNotExpired(_proposalId); isConfirmed[_proposalId] = true; ProposalState status = state(_proposalId); require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); @@ -242,6 +252,12 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { proposalTimeDelay = newProposalTimeDelay; } + function updateProposalLifetime(uint256 newProposalLifetime) public onlyMultiSig { + require(newProposalLifetime>= MINIMUM_LIFETIME, "updateProposalLifetime: updateProposalLifetime less than minimum"); + emit ProposalTimeDelayUpdated(newProposalLifetime, newProposalLifetime); + proposalLifetime = newProposalLifetime; + } + function emergencyStop() public onlyMultiSig { _pause(); } @@ -420,10 +436,9 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { bytes[] memory calldatas, bytes32 /*descriptionHash*/ ) internal virtual { - string memory errorMessage = "Governor: call reverted without message"; for (uint256 i = 0; i < targets.length; ++i) { (bool success, bytes memory returndata) = targets[i].call{ value: values[i] }(calldatas[i]); - Address.verifyCallResult(success, returndata, errorMessage); + emit ExecuteTransaction(msg.sender,success, returndata); } } @@ -572,6 +587,10 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { require(isConfirmed[_proposalId], "proposal not confirmed"); } + function requireNotExpired(uint256 _proposalId) internal view { + require(_proposals[_proposalId].expireTimestamp >= block.timestamp,"proposal expired"); + } + function _executor() internal view virtual returns (address) { return address(this); } diff --git a/contracts/dao/governance/GovernorStructs.sol b/contracts/dao/governance/GovernorStructs.sol index b8a79ff..8097e5b 100644 --- a/contracts/dao/governance/GovernorStructs.sol +++ b/contracts/dao/governance/GovernorStructs.sol @@ -11,4 +11,5 @@ struct ProposalCore { Timers.BlockNumber voteEnd; bool executed; bool canceled; + uint256 expireTimestamp; } diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index 7d8d8fe..9b72918 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -22,7 +22,6 @@ contract MainTokenGovernor is { using SafeERC20 for IERC20; mapping(address => bool) public isSupportedToken; - uint256 public constant EIGHT_HOURS = 28800; constructor( IVotes _token, @@ -30,9 +29,11 @@ contract MainTokenGovernor is address _multiSig, uint256 _initialVotingDelay, uint256 _votingPeriod, - uint256 _initialProposalThreshold + uint256 _initialProposalThreshold, + uint256 _proposalTimeDelay, + uint256 _proposalLifetime ) - Governor("MainTokenGovernor", _multiSig, 20, EIGHT_HOURS) + Governor("MainTokenGovernor", _multiSig, 20, _proposalTimeDelay,_proposalLifetime) GovernorSettings(_initialVotingDelay, _votingPeriod, _initialProposalThreshold) GovernorVotes(_token) GovernorVotesQuorumFraction(4) @@ -101,9 +102,9 @@ contract MainTokenGovernor is address target, bytes calldata data ) external payable virtual onlyGovernance { - require(isSupportedToken[target], "relay: token not supported"); + require(isSupportedToken[target], "relayERC20: token not supported"); (bool success, bytes memory returndata) = target.call(data); - Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); + Address.verifyCallResult(success, returndata, "Governor: relayERC20 reverted without message"); } /** @@ -112,13 +113,13 @@ contract MainTokenGovernor is * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. * Note that if the executor is simply the governor itself, use of `relay` is redundant. */ - function relayNativeToken( + function relayETH( address target, uint256 value, bytes calldata data ) external payable virtual onlyGovernance { (bool success, bytes memory returndata) = target.call{ value: value }(data); - Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); + Address.verifyCallResult(success, returndata, "Governor: relayETH reverted without message"); } function _execute( diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index 2614040..9a6c4ca 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -33,6 +33,8 @@ contract TimelockController is AccessControl, Initializable, ITimelockController */ event MinDelayChange(uint256 oldDuration, uint256 newDuration); + event ExecuteTransaction(address indexed owner, bool success, bytes data); + /** * @dev Modifier to make a function callable only by a certain role. In * addition to checking the sender's role, `address(0)` 's role is also @@ -149,16 +151,22 @@ contract TimelockController is AccessControl, Initializable, ITimelockController require(targets.length == payloads.length, "TimelockController: length mismatch"); bytes32 id = hashOperationBatch(targets, values, payloads, predecessor, salt); - + uint256 totalValue; _beforeCall(id, predecessor); for (uint256 i = 0; i < targets.length; ++i) { address target = targets[i]; uint256 value = values[i]; + totalValue += value; bytes memory payload = payloads[i]; _execute(target, value, payload); emit CallExecuted(id, i, target, value, payload); } _afterCall(id); + require(msg.value >= totalValue,"executeBatch: msg.value insufficient sent"); + if(msg.value > totalValue){ + (bool sent, ) = msg.sender.call{ value: (msg.value - totalValue) }(""); + require(sent, "Failed to send ether"); + } } function updateDelay(uint256 newDelay) public virtual { @@ -217,13 +225,23 @@ contract TimelockController is AccessControl, Initializable, ITimelockController return keccak256(abi.encode(targets, values, payloads, predecessor, salt)); } + function grantRoleByAdmin(bytes32 role, address account) public onlyRole(DEFAULT_ADMIN_ROLE) { + _grantRole(role, account); + } + + function revokeRoleByAdmin(bytes32 role, address account) public onlyRole(DEFAULT_ADMIN_ROLE) { + _revokeRole(role, account); + } + + + function _execute( address target, uint256 value, bytes memory data ) internal virtual { (bool success, ) = target.call{ value: value }(data); - require(success, "TimelockController: underlying transaction reverted"); + emit ExecuteTransaction(msg.sender,success, data); } function _afterCall(bytes32 id) private { diff --git a/contracts/dao/governance/extensions/GovernorTimelockControl.sol b/contracts/dao/governance/extensions/GovernorTimelockControl.sol index f42eada..ec6936b 100644 --- a/contracts/dao/governance/extensions/GovernorTimelockControl.sol +++ b/contracts/dao/governance/extensions/GovernorTimelockControl.sol @@ -31,7 +31,7 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { bytes32 descriptionHash ) public virtual override returns (uint256) { uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); - + require(isConfirmed[proposalId], "queue: not confirmed by multisig"); require(state(proposalId) == ProposalState.Succeeded, "Governor: proposal not successful"); uint256 delay = _timelock.getMinDelay(); diff --git a/contracts/dao/staking/helpers/IStakingGetterHelper.sol b/contracts/dao/staking/helpers/IStakingGetterHelper.sol index dce197e..fa30122 100644 --- a/contracts/dao/staking/helpers/IStakingGetterHelper.sol +++ b/contracts/dao/staking/helpers/IStakingGetterHelper.sol @@ -31,4 +31,5 @@ interface IStakingGetterHelper { function getFeesForEarlyUnlock(uint256 lockId, address account) external view returns (uint256); function getLocksLength(address account) external view returns (uint256); + function getWeight() external view returns (Weight memory); } diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index 8299a6d..75069af 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -10,8 +10,6 @@ import "../../../common/access/AccessControl.sol"; contract StakingGettersHelper is IStakingGetterHelper, AccessControl { address private stakingContract; - uint256 internal constant ONE_YEAR = 31536000; - uint256 internal constant WEEK = 604800; uint256 public constant WEIGHT_SLOT = 14; constructor(address _stakingContract, address admin) { stakingContract = _stakingContract; @@ -29,6 +27,9 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { LockedBalance[] memory locks = _getAllLocks(account); return locks.length; } + function getWeight() public view override returns (Weight memory) { + return _getWeight(); + } function getLock(address account, uint256 lockId) public @@ -99,10 +100,12 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { return penalty; } + function _getAllLocks(address account) internal view returns(LockedBalance[] memory) { return IStakingHelper(stakingContract).getAllLocks(account); } + function _weightedPenalty(uint256 lockEnd, uint256 timestamp) internal view returns (uint256) { Weight memory weight = _getWeight(); uint256 maxLockPeriod = IStakingHelper(stakingContract).maxLockPeriod(); @@ -117,7 +120,6 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { (weight.penaltyWeightMultiplier * (weight.maxWeightPenalty - weight.minWeightPenalty) * remainingTime) / maxLockPeriod); } - function _getWeight() internal view returns (Weight memory) { bytes32 weight = IStakingHelper(stakingContract).readBySlot(WEIGHT_SLOT); uint32 penaltyWeightMultiplier; @@ -127,15 +129,19 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { uint32 maxWeightShares; assembly { let value := weight - maxWeightShares := and(0xffff, value) + maxWeightShares := and(0xffffffff, value) + //shift right by 32 and do and by 32 bytes to get the value let shifted_2 := shr(32,value) - minWeightShares := and(0xffff, shifted_2) + minWeightShares := and(0xffffffff, shifted_2) + //shift right by 64 and do and by 32 bytes to get the value let shifted_3 := shr(64,value) - maxWeightPenalty := and(0xffff, shifted_3) + maxWeightPenalty := and(0xffffffff, shifted_3) + //shift right by 96 and do and by 32 bytes to get the value let shifted_4 := shr(96,value) - minWeightPenalty := and(0xffff, shifted_4) + minWeightPenalty := and(0xffffffff, shifted_4) + //shift right by 128 and do and by 32 bytes to get the value let shifted_5 := shr(128,value) - penaltyWeightMultiplier := and(0xffff, shifted_5) + penaltyWeightMultiplier := and(0xffffffff, shifted_5) } return Weight( diff --git a/contracts/dao/staking/library/RewardsLibrary.sol b/contracts/dao/staking/library/RewardsLibrary.sol index c251abd..bccff88 100644 --- a/contracts/dao/staking/library/RewardsLibrary.sol +++ b/contracts/dao/staking/library/RewardsLibrary.sol @@ -18,7 +18,6 @@ library RewardsLibrary { ) public view { require(streamOwner != address(0), "bad owner"); require(rewardToken != address(0), "bad reward token"); - require(maxDepositAmount > 0, "No Max Deposit"); require(minDepositAmount > 0, "No Min Deposit"); require(minDepositAmount <= maxDepositAmount, "bad Min Deposit"); require(maxDepositAmount == scheduleRewards[0], "Invalid Max Deposit"); diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index 3c50181..65fd3fd 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -32,11 +32,10 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { value := sload(slot) } } - - function getAllLocks(address account) external view returns (LockedBalance[] memory) { + //TODO: Do by assembly in staking getter helper. Almost done + function getAllLocks(address account) external override view returns (LockedBalance[] memory) { return locks[account]; } - // function getStream(uint256 streamId) // external // view diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index c51bc84..c4f8b4f 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -76,6 +76,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A rps: 0 }) ); + //TODO Remove: _adminPause(0); mainStreamInitialized =true; _transfer(scheduleRewards[0],mainToken); diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 0fbc705..c18f647 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -5,14 +5,13 @@ pragma solidity 0.8.13; import "./RewardsInternals.sol"; -import "../StakingStorage.sol"; import "../interfaces/IStakingEvents.sol"; import "../vault/interfaces/IVault.sol"; import "../../tokens/ERC20/IERC20.sol"; import "../../tokens/IVMainToken.sol"; import "../../../common/math/BoringMath.sol"; -contract StakingInternals is StakingStorage, RewardsInternals { +contract StakingInternals is RewardsInternals { // solhint-disable not-rely-on-time function _initializeStaking( address _mainToken, @@ -102,7 +101,7 @@ contract StakingInternals is StakingStorage, RewardsInternals { userAccount.voteTokenBalance = BoringMath.to128(remainingVoteTokenBalance); _unstake(amount, stakeValue, lockId, account); // This is for dust mitigation, so that even if the - // user does not hae enough voteToken, it is still able to burn and unlock + // user does not have enough voteToken, it is still able to burn and unlock // takes a bit of gas uint256 balance = IERC20(voteToken).balanceOf(account); if (balance < nVoteToken) { diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index cbc8bfe..4d6fc16 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -12,7 +12,6 @@ import "../../../../common/SafeERC20.sol"; // solhint-disable not-rely-on-time contract VaultPackage is IVault, IVaultEvents, AdminPausable { using SafeERC20 for IERC20; - bool private vaultInitialized; bytes32 public constant REWARDS_OPERATOR_ROLE = keccak256("REWARDS_OPERATOR_ROLE"); mapping(address => uint256) public deposited; mapping(address => bool) public override isSupportedToken; @@ -24,8 +23,6 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { } function initVault(address _admin, address[] calldata supportedTokens) external override initializer { - require(!vaultInitialized, "Vault: Already Initialized"); - vaultInitialized = true; for (uint256 i = 0; i < supportedTokens.length; i++) { _addSupportedToken(supportedTokens[i]); } @@ -85,7 +82,6 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { }else{ balanceToWithdraw = balanceInContract; } - if(balanceToWithdraw > 0){ IERC20(_token).transfer(_withdrawTo, balanceToWithdraw); } diff --git a/contracts/dao/tokens/VMainToken.sol b/contracts/dao/tokens/VMainToken.sol index b0cbf6e..6993442 100644 --- a/contracts/dao/tokens/VMainToken.sol +++ b/contracts/dao/tokens/VMainToken.sol @@ -13,7 +13,6 @@ contract VMainToken is IVMainToken, Pausable, AccessControl, Initializable, ERC2 bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE"); bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); - bool private initialized; // Mapping to keep track of who is allowed to transfer voting tokens mapping(address => bool) public isWhiteListed; diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index ef82028..802e7bf 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -34,6 +34,7 @@ contract MultiSigWallet is IMultiSigWallet { mapping(address => bytes32) internal whitelistedBytesCode; Transaction[] public transactions; + mapping(address => uint256[]) confirmedTransactions; modifier onlyOwnerOrGov() { require(isOwner[msg.sender] || governor == msg.sender, "MultiSig: MultiSigWallet, onlyOwnerOrGov(): Neither owner nor governor"); @@ -91,9 +92,7 @@ contract MultiSigWallet is IMultiSigWallet { ) { require(_expireTimestamp >= block.timestamp || _expireTimestamp == 0, "already expired"); - if (_to.isContract()) { - require(_data.length > 0, "no calldata for contract call"); - } else { + if (!_to.isContract()) { require(_data.length == 0 && _value > 0, "calldata for EOA call or 0 value"); } @@ -141,8 +140,16 @@ contract MultiSigWallet is IMultiSigWallet { if (numConfirmationsRequired > owners.length) changeRequirement(owners.length); - lastDisabledTransactionIndex = getTransactionCount(); - + uint256 nConfirmedTxnByOwner = confirmedTransactions[owner].length; + if(nConfirmedTxnByOwner > 0){ + for(uint i = 0; i < nConfirmedTxnByOwner; i++){ + uint256 _txIndex = confirmedTransactions[owner][i]; + Transaction storage transaction = transactions[_txIndex]; + transaction.numConfirmations -= 1; + isConfirmed[_txIndex][owner] = false; + emit RevokeConfirmation(owner, _txIndex); + } + } emit OwnerRemoval(owner); } @@ -174,19 +181,21 @@ contract MultiSigWallet is IMultiSigWallet { address _to, uint256 _value, bytes memory _data, - uint256 _expireTimestamp - ) public override onlyOwnerOrGov validateSubmitTxInputs(_to, _value, _data, _expireTimestamp) { + uint256 _lifetime + ) public override onlyOwnerOrGov validateSubmitTxInputs(_to, _value, _data, _lifetime) { require(address(this).balance >= _value, "submitTransaction: not enough balance"); - if (!_to.isContract()) { - require(_value != 0, "submitTransaction: value is zero"); - require(_data.length > 0, "submitTransaction: not equal"); - } uint256 txIndex = transactions.length; transactions.push( - Transaction({ to: _to, value: _value, data: _data, executed: false, numConfirmations: 0, expireTimestamp: _expireTimestamp }) + Transaction({ + to: _to, + value: _value, + data: _data, + executed: false, + numConfirmations: 0, + expireTimestamp: _lifetime == 0 ? 0 : block.timestamp + _lifetime }) ); - + whitelistedBytesCode[_to] = _to.getExtCodeHash(); emit SubmitTransaction(txIndex, msg.sender, _to, _value, _data); @@ -208,6 +217,7 @@ contract MultiSigWallet is IMultiSigWallet { transaction.numConfirmations += 1; isConfirmed[_txIndex][msg.sender] = true; + confirmedTransactions[msg.sender].push(_txIndex); emit ConfirmTransaction(msg.sender, _txIndex); } @@ -230,13 +240,8 @@ contract MultiSigWallet is IMultiSigWallet { transaction.executed = true; (bool success, bytes memory data) = transaction.to.call{ value: transaction.value }(transaction.data); - if (success) { - emit ExecuteTransaction(msg.sender, _txIndex); - } else { - revert TransactionRevered(data); - } - - emit ExecuteTransaction(msg.sender, _txIndex); + + emit ExecuteTransaction(msg.sender, _txIndex,success, data); } function revokeConfirmation(uint256 _txIndex) diff --git a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol index b2a07f3..ef53bb6 100644 --- a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol +++ b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol @@ -8,7 +8,7 @@ interface IMultiSigWallet { event SubmitTransaction(uint256 indexed txIndex, address indexed owner, address indexed to, uint256 value, bytes data); event ConfirmTransaction(address indexed owner, uint256 indexed txIndex); event RevokeConfirmation(address indexed owner, uint256 indexed txIndex); - event ExecuteTransaction(address indexed owner, uint256 indexed txIndex); + event ExecuteTransaction(address indexed owner, uint256 indexed txIndex, bool success,bytes data); event OwnerRemoval(address indexed owner); event OwnerAddition(address indexed owner); event RequirementChange(uint256 required); diff --git a/scripts/migrations/deployment/5_deploy_governor.js b/scripts/migrations/deployment/5_deploy_governor.js index adae8f3..f42b56b 100644 --- a/scripts/migrations/deployment/5_deploy_governor.js +++ b/scripts/migrations/deployment/5_deploy_governor.js @@ -9,6 +9,8 @@ const MultiSigWallet_address = MultiSigWallet.address; const initialVotingDelay = 1; const votingPeriod = 20; const initialProposalThreshold = 1000; +const proposalTimeDelay = 2; +const proposalLifetime = 86400; module.exports = async function(deployer) { @@ -21,6 +23,8 @@ module.exports = async function(deployer) { initialVotingDelay, votingPeriod, initialProposalThreshold, + proposalTimeDelay, + proposalLifetime, { gas: 12000000 }), ]; diff --git a/scripts/tests/dao/demo/staking.demo.test.js b/scripts/tests/dao/demo/staking.demo.test.js index 7b50d5d..23ff8ab 100644 --- a/scripts/tests/dao/demo/staking.demo.test.js +++ b/scripts/tests/dao/demo/staking.demo.test.js @@ -307,7 +307,7 @@ describe("Staking Test and Upgrade Test", () => { expectedTotalAmountOfVFTHM = new web3.utils.BN(0) it('Should create a lock possition with lockId = 1 for staker_1', async() => { // So that staker 1 can actually stake the token: - await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_1}) + await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_1}) const beforeFTHMBalance = await FTHMToken.balanceOf(staker_1); await blockchain.increaseTime(20); @@ -385,8 +385,8 @@ describe("Staking Test and Upgrade Test", () => { const sumToDepositForAll = web3.utils.toWei('0.11', 'ether'); - await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_2}) - await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_3}) + await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_2}) + await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_3}) await blockchain.mineBlock(await _getTimeStamp() + 20); console.log(".........Creating a Lock Position for staker 2 and Staker 3......."); @@ -590,7 +590,7 @@ describe("Staking Test and Upgrade Test", () => { console.log(".........Creating the stream proposed.........") console.log("Once create stream is called, the proposal will become live once start time is reached") const RewardProposalAmountForAStream = web3.utils.toWei('1000', 'ether'); - await streamReward2.approve(vaultService.address, RewardProposalAmountForAStream, {from:stream_rewarder_2}) + await streamReward2.approve(stakingService.address, RewardProposalAmountForAStream, {from:stream_rewarder_2}) await stakingService.createStream(streamId,RewardProposalAmountForAStream, {from: stream_rewarder_2}); }) diff --git a/scripts/tests/dao/full-flow-demo.test.js b/scripts/tests/dao/full-flow-demo.test.js index ee5cc69..dfa6056 100644 --- a/scripts/tests/dao/full-flow-demo.test.js +++ b/scripts/tests/dao/full-flow-demo.test.js @@ -419,7 +419,7 @@ describe("DAO Demo", () => { let expectedTotalAmountOfVFTHM = new web3.utils.BN(0) it('Should create a lock possition with lockId = 1 for staker_1', async() => { - await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_1}) + await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_1}) await blockchain.increaseTime(20); let lockingPeriod = 365 * 24 * 60 * 60; @@ -456,7 +456,7 @@ describe("DAO Demo", () => { }) it('Should create 2 lock positions with lockId = 1 and lockId = 2 for staker_2', async() => { - await FTHMToken.approve(vaultService.address, sumToApprove, {from: staker_2}); + await FTHMToken.approve(stakingService.address, sumToApprove, {from: staker_2}); await blockchain.increaseTime(20); let lockingPeriod = 365 * 24 * 60 * 60; @@ -531,7 +531,7 @@ describe("DAO Demo", () => { it("Should Create a stream, stream - 1", async() => { const streamId = 1 const RewardProposalAmountForAStream = web3.utils.toWei('1000', 'ether'); - await streamReward1.approve(vaultService.address, RewardProposalAmountForAStream, {from:stream_rewarder_1}); + await streamReward1.approve(stakingService.address, RewardProposalAmountForAStream, {from:stream_rewarder_1}); await stakingService.createStream(streamId,RewardProposalAmountForAStream, {from: stream_rewarder_1}); }); @@ -650,25 +650,7 @@ describe("DAO Demo", () => { expect((await mainTokenGovernor.state(proposalId)).toString()).to.equal("4"); }); - it('Queue the proposal', async() => { - - // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the - // description parameter, which we need to hash. - // - // A proposal can only be executed if the proposalId is the same as the one stored - // in the governer contract that has passed a vote. - // In the Governor.sol contract, the proposalId is created using all information used - // in to create the proposal: - // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); - - const result = await mainTokenGovernor.queue( - [box.address], - [0], - [encoded_function], - description_hash, - {"from": accounts[0]} - ); - }); + it('Create multiSig transaction to confirm proposal 1', async() => { @@ -692,7 +674,27 @@ describe("DAO Demo", () => { it('Execute the multiSig confirmation of proposal 1 and wait 40 blocks', async() => { await multiSigWallet.executeTransaction(txIndex1, {"from": accounts[0]}); + }); + + it('Queue the proposal', async() => { + + // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the + // description parameter, which we need to hash. + // + // A proposal can only be executed if the proposalId is the same as the one stored + // in the governer contract that has passed a vote. + // In the Governor.sol contract, the proposalId is created using all information used + // in to create the proposal: + // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); + const result = await mainTokenGovernor.queue( + [box.address], + [0], + [encoded_function], + description_hash, + {"from": accounts[0]} + ); + const currentNumber = await web3.eth.getBlockNumber(); const block = await web3.eth.getBlock(currentNumber); const timestamp = block.timestamp; @@ -877,15 +879,6 @@ describe("DAO Demo", () => { }); - it('Queue the second proposal', async() => { - await mainTokenGovernor.queue( - [multiSigWallet.address], - [0], - [encoded_treasury_function], - description_hash_2, - {"from": accounts[0]} - ); - }); it('Create multiSig transaction to confirm proposal 1', async() => { encodedConfirmation2 = _encodeConfirmation(proposalId2); @@ -908,7 +901,16 @@ describe("DAO Demo", () => { it('Execute the multiSig confirmation of proposal 1 and wait 40 blocks', async() => { await multiSigWallet.executeTransaction(txIndex2, {"from": accounts[0]}); + }); + it('Queue the second proposal', async() => { + await mainTokenGovernor.queue( + [multiSigWallet.address], + [0], + [encoded_treasury_function], + description_hash_2, + {"from": accounts[0]} + ); const currentNumber = await web3.eth.getBlockNumber(); const block = await web3.eth.getBlock(currentNumber); const timestamp = block.timestamp; @@ -919,9 +921,9 @@ describe("DAO Demo", () => { nextBlock++; } expect((await mainTokenGovernor.state(proposalId2)).toString()).to.equal("5"); + }); - it('Execute the second proposal', async() => { result = await mainTokenGovernor.execute( [multiSigWallet.address], @@ -964,7 +966,7 @@ describe("DAO Demo", () => { result = await multiSigWallet.submitTransaction( FTHMToken.address, EMPTY_BYTES, - _encodeStakeApproveFunction(approveAmount, vaultService.address), + _encodeStakeApproveFunction(approveAmount, stakingService.address), 0, {"from": accounts[0]} ); diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 0016cd3..c3dcd26 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -212,7 +212,7 @@ describe('Proposal flow', () => { const _stakeMainGetVe = async (_account) => { await _transferFromMultiSigTreasury(_account); - await FTHMToken.approve(vaultService.address, T_TO_STAKE, {from: _account}); + await FTHMToken.approve(stakingService.address, T_TO_STAKE, {from: _account}); await blockchain.increaseTime(20); let unlockTime = lockingPeriod; @@ -338,25 +338,7 @@ describe('Proposal flow', () => { expect((await mainTokenGovernor.state(proposalId)).toString()).to.equal("4"); }); - it('Queue the proposal', async() => { - - // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the - // description parameter, which we need to hash. - // - // A proposal can only be executed if the proposalId is the same as the one stored - // in the governer contract that has passed a vote. - // In the Governor.sol contract, the proposalId is created using all information used - // in to create the proposal: - // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); - - const result = await mainTokenGovernor.queue( - [box.address], - [0], - [encoded_function], - description_hash, - {"from": accounts[0]} - ); - }); + it('Create multiSig transaction to confirm proposal 1', async() => { @@ -380,7 +362,27 @@ describe('Proposal flow', () => { it('Execute the multiSig confirmation of proposal 1 and wait 40 blocks', async() => { await multiSigWallet.executeTransaction(txIndex1, {"from": accounts[0]}); + }); + + it('Queue the proposal', async() => { + // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the + // description parameter, which we need to hash. + // + // A proposal can only be executed if the proposalId is the same as the one stored + // in the governer contract that has passed a vote. + // In the Governor.sol contract, the proposalId is created using all information used + // in to create the proposal: + // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); + + const result = await mainTokenGovernor.queue( + [box.address], + [0], + [encoded_function], + description_hash, + {"from": accounts[0]} + ); + const currentNumber = await web3.eth.getBlockNumber(); const block = await web3.eth.getBlock(currentNumber); const timestamp = block.timestamp; @@ -438,7 +440,7 @@ describe('Proposal flow', () => { const _stakeMainGetVe = async (_account) => { await _transferFromMultiSigTreasury(_account); - await FTHMToken.approve(vaultService.address, T_TO_STAKE, {from: _account}); + await FTHMToken.approve(stakingService.address, T_TO_STAKE, {from: _account}); await blockchain.increaseTime(20); let unlockTime = lockingPeriod; @@ -543,15 +545,7 @@ describe('Proposal flow', () => { ); }); - it('Queue the second proposal', async() => { - await mainTokenGovernor.queue( - [multiSigWallet.address], - [0], - [encoded_treasury_function], - description_hash_2, - {"from": accounts[0]} - ); - }); + it('Create multiSig transaction to confirm proposal 1', async() => { encodedConfirmation1 = _encodeConfirmation(proposalId2); @@ -574,7 +568,17 @@ describe('Proposal flow', () => { it('Execute the multiSig confirmation of proposal 1 and wait 40 blocks', async() => { await multiSigWallet.executeTransaction(txIndex2, {"from": accounts[0]}); + }); + it('Queue the second proposal', async() => { + await mainTokenGovernor.queue( + [multiSigWallet.address], + [0], + [encoded_treasury_function], + description_hash_2, + {"from": accounts[0]} + ); + const currentNumber = await web3.eth.getBlockNumber(); const block = await web3.eth.getBlock(currentNumber); const timestamp = block.timestamp; @@ -585,6 +589,7 @@ describe('Proposal flow', () => { nextBlock++; } expect((await mainTokenGovernor.state(proposalId2)).toString()).to.equal("5"); + }); it('Wait 40 blocks and then check that the proposal status is: Queued', async() => { @@ -712,25 +717,7 @@ describe('Proposal flow', () => { expect((await mainTokenGovernor.state(proposalIdForAddingSupportedToken)).toString()).to.equal("4"); }); - it('Queue the proposal', async() => { - - // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the - // description parameter, which we need to hash. - // - // A proposal can only be executed if the proposalId is the same as the one stored - // in the governer contract that has passed a vote. - // In the Governor.sol contract, the proposalId is created using all information used - // in to create the proposal: - // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); - - const result = await mainTokenGovernor.queue( - [mainTokenGovernor.address], - [0], - [encoded_function_add_supporting_token], - description_hash, - {"from": accounts[0]} - ); - }); + it('Create multiSig transaction to confirm proposal for adding supported tokens', async() => { @@ -754,11 +741,31 @@ describe('Proposal flow', () => { it('Execute the multiSig confirmation of proposal 1 and wait 40 blocks', async() => { await multiSigWallet.executeTransaction(txIndex1, {"from": accounts[0]}); + }); + it('Queue the proposal', async() => { + + // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the + // description parameter, which we need to hash. + // + // A proposal can only be executed if the proposalId is the same as the one stored + // in the governer contract that has passed a vote. + // In the Governor.sol contract, the proposalId is created using all information used + // in to create the proposal: + // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); + + const result = await mainTokenGovernor.queue( + [mainTokenGovernor.address], + [0], + [encoded_function_add_supporting_token], + description_hash, + {"from": accounts[0]} + ); const currentNumber = await web3.eth.getBlockNumber(); const block = await web3.eth.getBlock(currentNumber); const timestamp = block.timestamp; + var nextBlock = 1; while (nextBlock <= 40) { await blockchain.mineBlock(timestamp + nextBlock); @@ -859,25 +866,7 @@ describe('Proposal flow', () => { expect((await mainTokenGovernor.state(proposalIdForRelayFunction)).toString()).to.equal("4"); }); - it('Queue the proposal', async() => { - - // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the - // description parameter, which we need to hash. - // - // A proposal can only be executed if the proposalId is the same as the one stored - // in the governer contract that has passed a vote. - // In the Governor.sol contract, the proposalId is created using all information used - // in to create the proposal: - // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); - - const result = await mainTokenGovernor.queue( - [mainTokenGovernor.address], - [0], - [encoded_function_relay], - description_hash, - {"from": accounts[0]} - ); - }); + it('Create multiSig transaction to confirm proposal for relaying supported tokens', async() => { @@ -901,17 +890,36 @@ describe('Proposal flow', () => { it('Execute the multiSig confirmation of proposal 1 and wait 40 blocks', async() => { await multiSigWallet.executeTransaction(txIndex1, {"from": accounts[0]}); + }); + + it('Queue the proposal', async() => { + // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the + // description parameter, which we need to hash. + // + // A proposal can only be executed if the proposalId is the same as the one stored + // in the governer contract that has passed a vote. + // In the Governor.sol contract, the proposalId is created using all information used + // in to create the proposal: + // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); + + const result = await mainTokenGovernor.queue( + [mainTokenGovernor.address], + [0], + [encoded_function_relay], + description_hash, + {"from": accounts[0]} + ); const currentNumber = await web3.eth.getBlockNumber(); const block = await web3.eth.getBlock(currentNumber); - const timestamp = block.timestamp; + const timestamp = block.timestamp; var nextBlock = 1; while (nextBlock <= 40) { await blockchain.mineBlock(timestamp + nextBlock); nextBlock++; } - expect((await mainTokenGovernor.state(proposalIdForRelayFunction)).toString()).to.equal("5"); + expect((await mainTokenGovernor.state(proposalIdForRelayFunction)).toString()).to.equal("5"); }); it('Execute the proposal', async() => { diff --git a/scripts/tests/dao/governance/token-creation-though-gov.test.js b/scripts/tests/dao/governance/token-creation-though-gov.test.js index 2a278b2..941494d 100644 --- a/scripts/tests/dao/governance/token-creation-though-gov.test.js +++ b/scripts/tests/dao/governance/token-creation-though-gov.test.js @@ -167,7 +167,7 @@ describe('Token Creation Through Governance', () => { const _stakeMainGetVe = async (_account) => { await _transferFromMultiSigTreasury(_account); - await FTHMToken.approve(vaultService.address, T_TO_STAKE, {from: _account}); + await FTHMToken.approve(stakingService.address, T_TO_STAKE, {from: _account}); await blockchain.increaseTime(20); let unlockTime = lockingPeriod; @@ -293,25 +293,7 @@ describe('Token Creation Through Governance', () => { expect((await mainTokenGovernor.state(proposalId)).toString()).to.equal("4"); }); - it('Queue the proposal', async() => { - - // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the - // description parameter, which we need to hash. - // - // A proposal can only be executed if the proposalId is the same as the one stored - // in the governer contract that has passed a vote. - // In the Governor.sol contract, the proposalId is created using all information used - // in to create the proposal: - // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); - - const result = await mainTokenGovernor.queue( - [erc20Factory.address], - [0], - [encoded_factory_function], - description_hash, - {"from": accounts[0]} - ); - }); + it('Create multiSig transaction to confirm proposal 1', async() => { @@ -335,6 +317,28 @@ describe('Token Creation Through Governance', () => { it('Execute the multiSig confirmation of proposal 1 and wait 40 blocks', async() => { await multiSigWallet.executeTransaction(txIndex1, {"from": accounts[0]}); + + + }); + + it('Queue the proposal', async() => { + + // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the + // description parameter, which we need to hash. + // + // A proposal can only be executed if the proposalId is the same as the one stored + // in the governer contract that has passed a vote. + // In the Governor.sol contract, the proposalId is created using all information used + // in to create the proposal: + // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); + + const result = await mainTokenGovernor.queue( + [erc20Factory.address], + [0], + [encoded_factory_function], + description_hash, + {"from": accounts[0]} + ); const currentNumber = await web3.eth.getBlockNumber(); const block = await web3.eth.getBlock(currentNumber); const timestamp = block.timestamp; From 63ea9ee05a25dd16d7ada75472eb84d0e143e4d2 Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 25 Jan 2023 16:36:05 +0545 Subject: [PATCH 29/77] doing audit fixes --- audit-report/Fathom_DAO-review.md | 2 ++ .../staking/helpers/StakingGettersHelper.sol | 26 +++++++++---------- .../dao/staking/interfaces/IStakingEvents.sol | 2 +- .../dao/staking/packages/StakingGetters.sol | 1 + .../dao/staking/packages/StakingHandler.sol | 11 ++++---- .../staking/vault/packages/VaultPackage.sol | 2 ++ scripts/tests/dao/staking/staking.test.js | 5 ---- 7 files changed, 23 insertions(+), 26 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 406103a..6d44248 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -466,6 +466,8 @@ The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contrac Despite checking that the `vault` is migrated, there is no validation that `_vault` is a compatible `VaultPackage`, which is the contract where the migration took place. We recommend adding new statement that `_vault` is `VaultPackage` for migration. +[accept this, as Admin will be sure to do it correctly] + #### [FIXED] There is no emergency suspension of the rewards payment in the `VaultPackage` contract ##### Description In the `VaultPackage` contract there is no possibility to suspend the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31). This causes the attacker to continue taking tokens from the contract if the address with `REWARDS_OPERATOR_ROLE`, such as `StakingHandlers` contract, is compromised. diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index 75069af..4a3e5e2 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -104,8 +104,6 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { function _getAllLocks(address account) internal view returns(LockedBalance[] memory) { return IStakingHelper(stakingContract).getAllLocks(account); } - - function _weightedPenalty(uint256 lockEnd, uint256 timestamp) internal view returns (uint256) { Weight memory weight = _getWeight(); uint256 maxLockPeriod = IStakingHelper(stakingContract).maxLockPeriod(); @@ -130,18 +128,18 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { assembly { let value := weight maxWeightShares := and(0xffffffff, value) - //shift right by 32 and do and by 32 bytes to get the value - let shifted_2 := shr(32,value) - minWeightShares := and(0xffffffff, shifted_2) - //shift right by 64 and do and by 32 bytes to get the value - let shifted_3 := shr(64,value) - maxWeightPenalty := and(0xffffffff, shifted_3) - //shift right by 96 and do and by 32 bytes to get the value - let shifted_4 := shr(96,value) - minWeightPenalty := and(0xffffffff, shifted_4) - //shift right by 128 and do and by 32 bytes to get the value - let shifted_5 := shr(128,value) - penaltyWeightMultiplier := and(0xffffffff, shifted_5) + //shift right by 32 then, do and by 32 bytes to get the value + let minWeightShares_shifted:= shr(32,value) + minWeightShares := and(0xffffffff, minWeightShares_shifted) + //shift right by 64 then, do and by 32 bytes to get the value + let maxWeightPenalty_shifted := shr(64,value) + maxWeightPenalty := and(0xffffffff, maxWeightPenalty_shifted) + //shift right by 96 then, do and by 32 bytes to get the value + let minWeightPenalty_shifted := shr(96,value) + minWeightPenalty := and(0xffffffff, minWeightPenalty_shifted) + //shift right by 128 then, do and by 32 bytes to get the value + let penaltyWeightMultiplier_shifted := shr(128,value) + penaltyWeightMultiplier := and(0xffffffff, penaltyWeightMultiplier_shifted) } return Weight( diff --git a/contracts/dao/staking/interfaces/IStakingEvents.sol b/contracts/dao/staking/interfaces/IStakingEvents.sol index d1ad4cc..754b779 100644 --- a/contracts/dao/staking/interfaces/IStakingEvents.sol +++ b/contracts/dao/staking/interfaces/IStakingEvents.sol @@ -9,7 +9,7 @@ interface IStakingEvents { event StreamProposed(uint256 indexed streamId, address indexed streamOwner, address indexed rewardToken, uint256 maxDepositAmount); event Released(uint256 indexed streamId, address indexed user, uint256 pendingAmount); event StreamProposalCancelled(uint256 indexed streamId, address indexed owner, address indexed token); - event StreamCreated(uint256 indexed streamId, address indexed owner, address indexed token, uint256[] scheduleRewards, uint256[] scheduleTimes); + event StreamCreated(uint256 indexed streamId, address indexed owner, address indexed token, uint256 tau,uint256[] scheduleRewards, uint256[] scheduleTimes); event StreamRemoved(uint256 indexed streamId, address indexed owner, address indexed token); event Unstaked(address indexed account, uint256 amount, uint256 indexed lockId); event PartialUnstaked(address indexed account, uint256 amount, uint256 indexed lockId); diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index 65fd3fd..3300d44 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -36,6 +36,7 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { function getAllLocks(address account) external override view returns (LockedBalance[] memory) { return locks[account]; } + //TODO: Somehow squeeze to get status or use assembly // function getStream(uint256 streamId) // external // view diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index c4f8b4f..0818019 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -20,7 +20,6 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A constructor() { _disableInitializers(); } - /** * @dev initialize the contract and deploys the first stream of rewards * @dev initializable only once due to stakingInitialised flag @@ -56,7 +55,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A uint256[] memory scheduleTimes, uint256[] memory scheduleRewards, uint256 tau - ) external override onlyRole(STREAM_MANAGER_ROLE) { + ) external override onlyRole(DEFAULT_ADMIN_ROLE) { require(!mainStreamInitialized,"init done"); _validateStreamParameters(_owner, mainToken, scheduleRewards[MAIN_STREAM], scheduleRewards[MAIN_STREAM], scheduleTimes, scheduleRewards, tau); uint256 streamId = 0; @@ -81,7 +80,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A mainStreamInitialized =true; _transfer(scheduleRewards[0],mainToken); emit StreamProposed(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); - emit StreamCreated(streamId, _owner, mainToken, scheduleRewards,scheduleTimes); + emit StreamCreated(streamId, _owner, mainToken, tau, scheduleRewards,scheduleTimes); } /** @@ -149,7 +148,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } require(stream.schedule.reward[0] == stream.rewardDepositAmount, "bad start"); - emit StreamCreated(streamId, stream.owner, stream.rewardToken,stream.schedule.time, stream.schedule.reward); + emit StreamCreated(streamId, stream.owner, stream.rewardToken,stream.tau,stream.schedule.time, stream.schedule.reward); _transfer(rewardTokenAmount,stream.rewardToken); } @@ -269,8 +268,8 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A // enforce pausing this contract before updating the address. // This mitigates the risk of future invalid reward claims require(paused != 0, "require pause"); - require(_vault != address(0), "zero addr"); - require(IVault(vault).migrated(), "nt migrated"); + require(_vault != address(0), "0 addr"); + require(IVault(vault).migrated(), "!migrated"); vault = _vault; } diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index 4d6fc16..e7f7a72 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -117,4 +117,6 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { } listOfSupportedTokens.pop(); } + + } diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index e7586b7..a41d600 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -1135,11 +1135,6 @@ describe("Staking Test", () => { const sumToDeposit = web3.utils.toWei('20000', 'ether'); let result1 = await stakingService.createLock(sumToDeposit,unlockTime, {from: accounts[9], gas: maxGasForTxn}); - - let eventArgs = eventsHelper.getIndexedEventArgs(result1, "Staked(address,uint256,uint256,uint256,uint256,uint256)"); - const actualNVFTHM = web3.utils.toBN(eventArgs[1]) - console.log("Are 20000 VOTE TOKENS released?: ", _convertToEtherBalance(actualNVFTHM.toString())) - }) it("Should get correct user total votes from staking getter service", async() => { From 4573b95049a7acae5a63eead6a7cdd557451ed78 Mon Sep 17 00:00:00 2001 From: ssubik Date: Fri, 27 Jan 2023 18:42:40 +0545 Subject: [PATCH 30/77] adding fixes in Multisig and checking for overflows --- audit-report/Fathom_DAO-review.md | 24 ++++++++++- contracts/common/math/BoringMath.sol | 7 +-- contracts/dao/governance/Governor.sol | 1 - contracts/dao/staking/StakingStructs.sol | 2 +- .../dao/staking/packages/StakingHandler.sol | 2 +- .../dao/staking/packages/StakingInternals.sol | 6 ++- .../dao/staking/vault/interfaces/IVault.sol | 6 ++- .../staking/vault/packages/VaultPackage.sol | 43 +++++++++++++------ 8 files changed, 66 insertions(+), 25 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 6d44248..06310e6 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -917,7 +917,7 @@ We recommend adding a check that `newProposalThreshold` is not zero. ###### Fathom's response Implemented Auditors Recommendation. -#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE: Keep an array of proposals and loop? Ask MAXJI -ASK AUDITOR] +#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor` ##### Description In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. ##### Recommendation @@ -1006,6 +1006,26 @@ Done where feasible for contract size ###### Oxorio's response We recommend fixing these issues completely, if there is already a problem with the size of the contract, then the code needs to be refactored. +Here: + [`StakingInternals.sol#L45`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L45) + + Our total Supply is 1 billion. Even if we have 100 billion total supply, the above line will not overflow as, + + nVoteToken = (amount * lockPeriod * POINT_MULTIPLIER) / voteLockCoef / POINT_MULTIPLIER + + nVoteToken = 100 * 1e9(amount) * 1e9(lock period) * 1e18(Point Multiplier) / 500 (VoteLockCoef)/ 1e18 (Point Multiplier) + ~= appr.1 e38, + But since nVoteToken in appr.1e77, it will not overflow + + + - [`StakingInternals.sol#L47`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L47) + + I converted uint128 to uint256 for voteTokenBalance + + -[`StakingInternals.sol#L227-L230`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L227-L230) + + This will not overflow as maxWeightShares, minWeightShares are always less than 1e6 at max. + #### [NO_ISSUE] Multiple `streams` can be active at the same time with the same parameters in `StakingHandler.sol ` ##### Description In the contract [StakingHandler]( @@ -1337,7 +1357,7 @@ We recommend changing it to: ``` -#### [NEW] Redundant check for `maxDepositAmount > 0` in `RewardsCalculator` +#### [NEW] Redundant check for `maxDepositAmount > 0` in `RewardsCalculator`[DONE] ##### Description diff --git a/contracts/common/math/BoringMath.sol b/contracts/common/math/BoringMath.sol index dd06c1b..5c0c33c 100644 --- a/contracts/common/math/BoringMath.sol +++ b/contracts/common/math/BoringMath.sol @@ -28,9 +28,10 @@ library BoringMath { c = uint224(a); } - function to208(uint256 a) internal pure returns (uint208 c) { - require(a <= type(uint208).max, "BoringMath: uint128 Overflow"); - c = uint208(a); + + function to160(uint256 a) internal pure returns (uint208 c) { + require(a <= type(uint160).max, "BoringMath: uint128 Overflow"); + c = uint160(a); } function to128(uint256 a) internal pure returns (uint128 c) { diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index ef13df1..043b521 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -88,7 +88,6 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { multiSig = multiSig_; maxTargets = maxTargets_; proposalTimeDelay = proposalTimeDelay_; - //TODO Updateable proposalLifetime = proposalLifetime_; } diff --git a/contracts/dao/staking/StakingStructs.sol b/contracts/dao/staking/StakingStructs.sol index 5578e26..b1c59ad 100644 --- a/contracts/dao/staking/StakingStructs.sol +++ b/contracts/dao/staking/StakingStructs.sol @@ -20,7 +20,7 @@ struct Schedule { } struct User { - uint128 voteTokenBalance; + uint256 voteTokenBalance; //streamId => pendings mapping(uint256 => uint256) pendings; // The amount of tokens pending release for user per stream //streamId => releaseTime diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 0818019..cbde664 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -75,7 +75,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A rps: 0 }) ); - //TODO Remove: + //TODO Remove and make deployment for unpause _adminPause(0); mainStreamInitialized =true; _transfer(scheduleRewards[0],mainToken); diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index c18f647..928c015 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -10,6 +10,8 @@ import "../vault/interfaces/IVault.sol"; import "../../tokens/ERC20/IERC20.sol"; import "../../tokens/IVMainToken.sol"; import "../../../common/math/BoringMath.sol"; +import "../../../common/math/FullMath.sol"; + contract StakingInternals is RewardsInternals { // solhint-disable not-rely-on-time @@ -48,7 +50,7 @@ contract StakingInternals is RewardsInternals { User storage userAccount = users[account]; if (lockPeriod > 0) { nVoteToken = (amount * lockPeriod * POINT_MULTIPLIER) / voteLockCoef / POINT_MULTIPLIER; //maxVoteTokens; - userAccount.voteTokenBalance += BoringMath.to128(nVoteToken); + userAccount.voteTokenBalance += nVoteToken; totalAmountOfVoteToken += nVoteToken; } LockedBalance memory _newLock = LockedBalance({ @@ -98,7 +100,7 @@ contract StakingInternals is RewardsInternals { if (userAccount.voteTokenBalance > nVoteToken) { remainingVoteTokenBalance = userAccount.voteTokenBalance - nVoteToken; } - userAccount.voteTokenBalance = BoringMath.to128(remainingVoteTokenBalance); + userAccount.voteTokenBalance = remainingVoteTokenBalance; _unstake(amount, stakeValue, lockId, account); // This is for dust mitigation, so that even if the // user does not have enough voteToken, it is still able to burn and unlock diff --git a/contracts/dao/staking/vault/interfaces/IVault.sol b/contracts/dao/staking/vault/interfaces/IVault.sol index 84201d6..28ce113 100644 --- a/contracts/dao/staking/vault/interfaces/IVault.sol +++ b/contracts/dao/staking/vault/interfaces/IVault.sol @@ -23,9 +23,13 @@ interface IVault { function migrate(address vaultPackageMigrateTo) external; + function withdrawExtraSupportedTokens(address _withdrawTo) external; + + function withdrawExtraUnsupportedToken(address _token,address _withdrawTo) external; + function isSupportedToken(address token) external view returns (bool); function migrated() external view returns (bool); - function withdrawExtraTokens(address _token, address _withdrawTo) external; + } diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index e7f7a72..0c486ba 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -42,8 +42,11 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { require(isSupportedToken[_token], "Unsupported token"); require(_amount != 0, "amount zero"); require(deposited[_token] >= _amount, "payRewards: not enough deposit"); - deposited[_token] -= _amount; + uint256 previousBalance = IERC20(_token).balanceOf(address(this)); IERC20(_token).safeTransfer(_user, _amount); + uint256 newBalance = IERC20(_token).balanceOf(address(this)); + uint256 trueDeposit = previousBalance - newBalance; + deposited[_token] -= trueDeposit; } function deposit( @@ -52,11 +55,14 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { ) external override pausable(1) { require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "deposit: No role"); require(isSupportedToken[_token], "Unsupported token"); - deposited[_token] += _amount; + uint256 previousBalance = IERC20(_token).balanceOf(address(this)); IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount); + uint256 newBalance = IERC20(_token).balanceOf(address(this)); + uint256 trueDeposit = newBalance - previousBalance; + deposited[_token] += trueDeposit; } - /// @notice adds token as a supproted rewards token by Vault + /// @notice adds token as a supported rewards token by Vault /// supported tokens means any future stream token should be /// whitelisted here /// @param _token stream ERC20 token address @@ -64,7 +70,7 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { _addSupportedToken(_token); } - /// @notice removed token as a supproted rewards token by Treasury + /// @notice removed token as a supported rewards token by Treasury /// @param _token stream ERC20 token address function removeSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) { require(isSupportedToken[_token], "Token does not exist"); @@ -74,19 +80,29 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { emit TokenRemoved(_token, msg.sender, block.timestamp); } - function withdrawExtraTokens(address _token, address _withdrawTo) external override onlyRole(DEFAULT_ADMIN_ROLE) { - uint256 balanceToWithdraw; + function withdrawExtraSupportedTokens(address _withdrawTo) external override onlyRole(DEFAULT_ADMIN_ROLE) { + for(uint i = 0; i < listOfSupportedTokens.length;i++){ + uint256 balanceToWithdraw; + address _token = listOfSupportedTokens[i]; + uint256 balanceInContract = IERC20(_token).balanceOf(address(this)); + if(balanceInContract > deposited[_token]){ + balanceToWithdraw = balanceInContract - deposited[_token]; + } + if(balanceToWithdraw > 0){ + IERC20(_token).transfer(_withdrawTo, balanceToWithdraw); + } + } + } + + function withdrawExtraUnsupportedToken(address _token,address _withdrawTo) external override onlyRole(DEFAULT_ADMIN_ROLE) { + require(!isSupportedToken[_token],"token is supported"); uint256 balanceInContract = IERC20(_token).balanceOf(address(this)); - if(isSupportedToken[_token] && balanceInContract > deposited[_token]){ - balanceToWithdraw = balanceInContract - deposited[_token]; - }else{ - balanceToWithdraw = balanceInContract; - } - if(balanceToWithdraw > 0){ - IERC20(_token).transfer(_withdrawTo, balanceToWithdraw); + if(balanceInContract > 0){ + IERC20(_token).transfer(_withdrawTo, balanceInContract); } } + /// @notice we believe newVaultPackage is safe function migrate(address newVaultPackage) external override onlyRole(DEFAULT_ADMIN_ROLE) { require(!migrated, "vault already migrated"); @@ -118,5 +134,4 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { listOfSupportedTokens.pop(); } - } From 88cce088cb9c891c39dd1cea37796cb603e96a58 Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 30 Jan 2023 19:29:42 +0545 Subject: [PATCH 31/77] implementing audit fixes - for multisig revoke and assembly --- audit-report/Fathom_DAO-review.md | 16 +++++++------ contracts/common/SafeERC20Staking.sol | 1 - contracts/common/math/FullMath.sol | 19 --------------- .../staking/helpers/StakingGettersHelper.sol | 13 +++++----- .../dao/staking/interfaces/IStakingGetter.sol | 5 +++- .../dao/staking/library/RewardsLibrary.sol | 12 ++++++---- .../staking/packages/RewardsCalculator.sol | 3 +-- .../dao/staking/packages/RewardsInternals.sol | 8 +++---- .../dao/staking/packages/StakingGetters.sol | 23 ++++-------------- .../dao/staking/packages/StakingHandler.sol | 4 ++-- contracts/dao/treasury/MultiSigWallet.sol | 24 ++++++++++--------- 11 files changed, 51 insertions(+), 77 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 06310e6..8045928 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -346,7 +346,7 @@ We recommend adding a constant with the minimum allowable value of `_quorumNumer Implemented Auditors Recommendation. -#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update +#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE] ##### Description In the [VMainToken](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) contract, for mint tokens, calling account, in addition to having `MINTER_ROLE` rights, must also be in the `isWhiteListed` list, since the mint function calls `_mint,` which contains [`_beforeTokenTransfer`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65) call. When `_beforeTokenTransfer` is called, it checks that the `msg.sender` address is in the `isWhiteListed` list. @@ -917,7 +917,7 @@ We recommend adding a check that `newProposalThreshold` is not zero. ###### Fathom's response Implemented Auditors Recommendation. -#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor` +#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE, check again] ##### Description In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. ##### Recommendation @@ -980,7 +980,7 @@ We recommend adding a condition that `createStream` can only be called from the ###### Fathom's response Implemented Auditors Recommendation. -#### 8. [NEW] Possible overflow with calculations[NOTDONE] +#### 8. [NEW] Possible overflow with calculations[NOTDONE]//TODO ##### Description In the next lines there is a possible overflow: @@ -988,9 +988,9 @@ In the next lines there is a possible overflow: - [`RewardsLibrary.sol#L71`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L71) - [`RewardsLibrary.sol#L78`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L78) - [`RewardsLibrary.sol#L8`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L84) -- [`RewardsCalculator.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L70) -- [`RewardsCalculator.sol#L77`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L77) -- [`RewardsCalculator.sol#L83`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L83) +- [`RewardsCalculator.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L70)[DONE] +- [`RewardsCalculator.sol#L77`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L77)[DONE] +- [`RewardsCalculator.sol#L83`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L83)[DONE] - [`RewardsInternals.sol#L15`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsInternals.sol#L15) - [`RewardsInternals.sol#L24-L25`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsInternals.sol#L24-L25) - [`StakingInternals.sol#L47`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L47) @@ -1024,7 +1024,9 @@ Here: -[`StakingInternals.sol#L227-L230`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L227-L230) - This will not overflow as maxWeightShares, minWeightShares are always less than 1e6 at max. + This will not overflow as maxWeightShares, minWeightShares are always less than 1e9 at max. + + Others done #### [NO_ISSUE] Multiple `streams` can be active at the same time with the same parameters in `StakingHandler.sol ` ##### Description diff --git a/contracts/common/SafeERC20Staking.sol b/contracts/common/SafeERC20Staking.sol index 323a5ca..b9d0fa1 100644 --- a/contracts/common/SafeERC20Staking.sol +++ b/contracts/common/SafeERC20Staking.sol @@ -47,7 +47,6 @@ library SafeERC20Staking { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } - /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). diff --git a/contracts/common/math/FullMath.sol b/contracts/common/math/FullMath.sol index e357426..1c1c5b0 100644 --- a/contracts/common/math/FullMath.sol +++ b/contracts/common/math/FullMath.sol @@ -106,23 +106,4 @@ library FullMath { return result; } } - - /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 - /// @param a The multiplicand - /// @param b The multiplier - /// @param denominator The divisor - /// @return result The 256-bit result - function mulDivRoundingUp( - uint256 a, - uint256 b, - uint256 denominator - ) internal pure returns (uint256 result) { - unchecked { - result = mulDiv(a, b, denominator); - if (mulmod(a, b, denominator) > 0) { - require(result < type(uint256).max); - result++; - } - } - } } diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index 4a3e5e2..8bbee53 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -10,7 +10,7 @@ import "../../../common/access/AccessControl.sol"; contract StakingGettersHelper is IStakingGetterHelper, AccessControl { address private stakingContract; - uint256 public constant WEIGHT_SLOT = 14; + uint256 public constant WEIGHT_SLOT = 14; // the storage slot in staking contract where WEIGHT resides constructor(address _stakingContract, address admin) { stakingContract = _stakingContract; _grantRole(DEFAULT_ADMIN_ROLE, admin); @@ -124,24 +124,23 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { uint32 minWeightPenalty; uint32 maxWeightPenalty; uint32 minWeightShares; - uint32 maxWeightShares; + uint32 maxWeightShares; assembly { let value := weight maxWeightShares := and(0xffffffff, value) - //shift right by 32 then, do and by 32 bytes to get the value + //shift right by 32 then, do and by 32 bits to get the value let minWeightShares_shifted:= shr(32,value) minWeightShares := and(0xffffffff, minWeightShares_shifted) - //shift right by 64 then, do and by 32 bytes to get the value + //shift right by 64 then, do and by 32 bits to get the value let maxWeightPenalty_shifted := shr(64,value) maxWeightPenalty := and(0xffffffff, maxWeightPenalty_shifted) - //shift right by 96 then, do and by 32 bytes to get the value + //shift right by 96 then, do and by 32 bits to get the value let minWeightPenalty_shifted := shr(96,value) minWeightPenalty := and(0xffffffff, minWeightPenalty_shifted) - //shift right by 128 then, do and by 32 bytes to get the value + //shift right by 128 then, do and by 32 bits to get the value let penaltyWeightMultiplier_shifted := shr(128,value) penaltyWeightMultiplier := and(0xffffffff, penaltyWeightMultiplier_shifted) } - return Weight( maxWeightShares, minWeightShares, diff --git a/contracts/dao/staking/interfaces/IStakingGetter.sol b/contracts/dao/staking/interfaces/IStakingGetter.sol index 418948f..2166fdd 100644 --- a/contracts/dao/staking/interfaces/IStakingGetter.sol +++ b/contracts/dao/staking/interfaces/IStakingGetter.sol @@ -30,11 +30,14 @@ interface IStakingGetter { uint256 lockId ) external view returns (uint256); function readBySlot(uint256 slot) external view returns(bytes32); - //function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); + //function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); // function getStreamsCount() external view returns (uint256); // function getLatestRewardsPerShare(uint256 streamId) external view returns (uint256); // function getWeight() external view returns (Weight memory); + // function getStreamStatus(uint256 streamId) external view returns ( + // StreamStatus status + // ); } diff --git a/contracts/dao/staking/library/RewardsLibrary.sol b/contracts/dao/staking/library/RewardsLibrary.sol index bccff88..e5d9a54 100644 --- a/contracts/dao/staking/library/RewardsLibrary.sol +++ b/contracts/dao/staking/library/RewardsLibrary.sol @@ -4,6 +4,7 @@ pragma solidity 0.8.13; import "../StakingStructs.sol"; +import "../../../common/math/FullMath.sol"; library RewardsLibrary { // solhint-disable not-rely-on-time @@ -71,20 +72,23 @@ library RewardsLibrary { if (startIndex == endIndex) { // start and end are within the same schedule period reward = schedule.reward[startIndex] - schedule.reward[startIndex + 1]; - rewardScheduledAmount = (reward * (end - start)) / (schedule.time[startIndex + 1] - schedule.time[startIndex]); + rewardScheduledAmount = FullMath.mulDiv(reward, (end - start), (schedule.time[startIndex + 1] - schedule.time[startIndex])); } else { // start and end are not within the same schedule period // Reward during the startIndex period // Here reward = starting from the actual start time, calculated for the first schedule period // that the rewards start. reward = schedule.reward[startIndex] - schedule.reward[startIndex + 1]; - rewardScheduledAmount = (reward * (schedule.time[startIndex + 1] - start)) / (schedule.time[startIndex + 1] - schedule.time[startIndex]); - // Here reward = from end of start schedule till beginning of end schedule + rewardScheduledAmount = FullMath.mulDiv(reward,(schedule.time[startIndex + 1] - start),(schedule.time[startIndex + 1] - schedule.time[startIndex])); // Here reward = from end of start schedule till beginning of end schedule // Reward during the period from startIndex + 1 to endIndex rewardScheduledAmount += schedule.reward[startIndex + 1] - schedule.reward[endIndex]; // Reward at the end schedule where schedule.time[endIndex] reward = schedule.reward[endIndex] - schedule.reward[endIndex + 1]; - rewardScheduledAmount += (reward * (end - schedule.time[endIndex])) / (schedule.time[endIndex + 1] - schedule.time[endIndex]); + rewardScheduledAmount += FullMath.mulDiv( + reward, + (end - schedule.time[endIndex]), + (schedule.time[endIndex + 1] - schedule.time[endIndex]) + ); } return rewardScheduledAmount; } diff --git a/contracts/dao/staking/packages/RewardsCalculator.sol b/contracts/dao/staking/packages/RewardsCalculator.sol index a924996..bd261e5 100644 --- a/contracts/dao/staking/packages/RewardsCalculator.sol +++ b/contracts/dao/staking/packages/RewardsCalculator.sol @@ -72,14 +72,13 @@ contract RewardsCalculator is IRewardsHandler { // start and end are within the same schedule period reward = schedule.reward[startIndex] - schedule.reward[startIndex + 1]; rewardScheduledAmount = FullMath.mulDiv(reward, (end - start), (schedule.time[startIndex + 1] - schedule.time[startIndex])); - rewardScheduledAmount = (reward * (end - start)) / (schedule.time[startIndex + 1] - schedule.time[startIndex]); } else { // start and end are not within the same schedule period // Reward during the startIndex period // Here reward = starting from the actual start time, calculated for the first schedule period // that the rewards start. reward = schedule.reward[startIndex] - schedule.reward[startIndex + 1]; - rewardScheduledAmount = (reward * (schedule.time[startIndex + 1] - start)) / (schedule.time[startIndex + 1] - schedule.time[startIndex]); + rewardScheduledAmount = FullMath.mulDiv(reward,(schedule.time[startIndex + 1] - start),(schedule.time[startIndex + 1] - schedule.time[startIndex])); // Here reward = from end of start schedule till beginning of end schedule // Reward during the period from startIndex + 1 to endIndex rewardScheduledAmount += schedule.reward[startIndex + 1] - schedule.reward[endIndex]; diff --git a/contracts/dao/staking/packages/RewardsInternals.sol b/contracts/dao/staking/packages/RewardsInternals.sol index 3bd1904..c82049b 100644 --- a/contracts/dao/staking/packages/RewardsInternals.sol +++ b/contracts/dao/staking/packages/RewardsInternals.sol @@ -6,13 +6,14 @@ pragma solidity 0.8.13; import "../StakingStorage.sol"; import "../interfaces/IStakingEvents.sol"; import "../interfaces/IRewardsHandler.sol"; +import "../../../common/math/FullMath.sol"; contract RewardsInternals is StakingStorage, IStakingEvents { // solhint-disable not-rely-on-time function _updateStreamsRewardsSchedules(uint256 streamId, uint256 rewardTokenAmount) internal { uint256 streamScheduleRewardLength = streams[streamId].schedule.reward.length; for (uint256 i = 0; i < streamScheduleRewardLength; i++) { - streams[streamId].schedule.reward[i] = (streams[streamId].schedule.reward[i] * rewardTokenAmount) / streams[streamId].maxDepositAmount; + streams[streamId].schedule.reward[i] = FullMath.mulDiv(streams[streamId].schedule.reward[i], rewardTokenAmount, streams[streamId].maxDepositAmount); } } @@ -25,8 +26,7 @@ contract RewardsInternals is StakingStorage, IStakingEvents { require(streams[streamId].status == StreamStatus.ACTIVE, "inactive"); User storage userAccount = users[account]; require(lock.amountOfToken != 0, "No Stake"); - uint256 reward = ((streams[streamId].rps - userAccount.rpsDuringLastClaimForLock[lockId][streamId]) * lock.positionStreamShares) / - RPS_MULTIPLIER; + uint256 reward = FullMath.mulDiv((streams[streamId].rps - userAccount.rpsDuringLastClaimForLock[lockId][streamId]), lock.positionStreamShares, RPS_MULTIPLIER); if (reward == 0) return; // All rewards claimed or stream schedule didn't start userAccount.pendings[streamId] += reward; streamTotalUserPendings[streamId] += reward; @@ -92,7 +92,7 @@ contract RewardsInternals is StakingStorage, IStakingEvents { } function _getLatestRewardsPerShare(uint256 streamId) internal view returns (uint256) { - require(totalStreamShares != 0, "No Stream Shares"); + require(totalStreamShares != 0, "No Shares"); return streams[streamId].rps + (_getRewardsAmount(streamId, touchedAt) * RPS_MULTIPLIER) / totalStreamShares; } } diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index 3300d44..15ee56c 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -9,7 +9,7 @@ import "../interfaces/IStakingGetter.sol"; import "./StakingInternals.sol"; contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { - function getUsersPendingRewards(address account, uint256 streamId) external view override returns (uint256) { + function getUsersPendingRewards(address account, uint256 streamId) external override view returns (uint256) { return users[account].pendings[streamId]; } function getStreamClaimableAmountPerLock( @@ -36,32 +36,17 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { function getAllLocks(address account) external override view returns (LockedBalance[] memory) { return locks[account]; } - //TODO: Somehow squeeze to get status or use assembly - // function getStream(uint256 streamId) + //TODO: Do by assembly in staking getter helper. Almost done + // function getStreamStatus(uint256 streamId) // external // view // override // returns ( - // address streamOwner, - // address rewardToken, - // uint256 rewardDepositAmount, - // uint256 rewardClaimedAmount, - // uint256 maxDepositAmount, - // uint256 rps, - // uint256 tau, // StreamStatus status // ) // { - // Stream storage stream = streams[streamId]; // return ( - // stream.owner, - // stream.rewardToken, - // stream.rewardDepositAmount, - // stream.rewardClaimedAmount, - // stream.maxDepositAmount, - // stream.rps, - // stream.tau, - // stream.status + // streams[streamId].status // ); // } diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index cbde664..61f63fc 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -75,7 +75,6 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A rps: 0 }) ); - //TODO Remove and make deployment for unpause _adminPause(0); mainStreamInitialized =true; _transfer(scheduleRewards[0],mainToken); @@ -186,7 +185,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _createLock(lockParams[i].amount, lockParams[i].lockPeriod, account); } } - + function createLock(uint256 amount, uint256 lockPeriod) public override pausable(1) { _createLock(amount, lockPeriod, msg.sender); } @@ -301,6 +300,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function _transfer(uint256 _amount, address _token) internal { IERC20(_token).safeTransferFrom(msg.sender,address(this),_amount); + IERC20(_token).safeApprove(vault,0); IERC20(_token).safeApprove(vault,_amount); IVault(vault).deposit(_token, _amount); } diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 802e7bf..570f0c2 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -5,7 +5,7 @@ pragma solidity 0.8.13; import "./interfaces/IMultiSigWallet.sol"; import "../../common/Address.sol"; - +import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; contract MultiSigWallet is IMultiSigWallet { using Address for address; @@ -36,6 +36,7 @@ contract MultiSigWallet is IMultiSigWallet { Transaction[] public transactions; mapping(address => uint256[]) confirmedTransactions; + modifier onlyOwnerOrGov() { require(isOwner[msg.sender] || governor == msg.sender, "MultiSig: MultiSigWallet, onlyOwnerOrGov(): Neither owner nor governor"); _; @@ -56,11 +57,6 @@ contract MultiSigWallet is IMultiSigWallet { _; } - modifier notDisabled(uint256 _txIndex) { - require(_txIndex >= lastDisabledTransactionIndex, "MultiSig: old txs has been disabled"); - _; - } - modifier notExpired(uint256 _txIndex) { require(transactions[_txIndex].expireTimestamp >= block.timestamp || transactions[_txIndex].expireTimestamp == 0, "MultiSig: tx expired"); _; @@ -142,11 +138,12 @@ contract MultiSigWallet is IMultiSigWallet { uint256 nConfirmedTxnByOwner = confirmedTransactions[owner].length; if(nConfirmedTxnByOwner > 0){ - for(uint i = 0; i < nConfirmedTxnByOwner; i++){ - uint256 _txIndex = confirmedTransactions[owner][i]; + for(uint i = nConfirmedTxnByOwner; i >1; i--){ + uint256 _txIndex = confirmedTransactions[owner][i-1]; Transaction storage transaction = transactions[_txIndex]; transaction.numConfirmations -= 1; isConfirmed[_txIndex][owner] = false; + confirmedTransactions[owner].pop(); emit RevokeConfirmation(owner, _txIndex); } } @@ -208,7 +205,6 @@ contract MultiSigWallet is IMultiSigWallet { txExists(_txIndex) notExecuted(_txIndex) notConfirmed(_txIndex) - notDisabled(_txIndex) notExpired(_txIndex) { Transaction storage transaction = transactions[_txIndex]; @@ -228,7 +224,6 @@ contract MultiSigWallet is IMultiSigWallet { onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) - notDisabled(_txIndex) notExpired(_txIndex) { Transaction storage transaction = transactions[_txIndex]; @@ -250,7 +245,6 @@ contract MultiSigWallet is IMultiSigWallet { onlyOwnerOrGov txExists(_txIndex) notExecuted(_txIndex) - notDisabled(_txIndex) notExpired(_txIndex) { Transaction storage transaction = transactions[_txIndex]; @@ -259,6 +253,14 @@ contract MultiSigWallet is IMultiSigWallet { transaction.numConfirmations -= 1; isConfirmed[_txIndex][msg.sender] = false; + + for (uint256 i = 0; i < confirmedTransactions[msg.sender].length - 1; i++) + if (confirmedTransactions[msg.sender][i] == _txIndex) { + confirmedTransactions[msg.sender][i] + = confirmedTransactions[msg.sender][confirmedTransactions[msg.sender].length - 1]; + break; + } + confirmedTransactions[msg.sender].pop(); emit RevokeConfirmation(msg.sender, _txIndex); } From 434ecbf0220796dbae51c1116c0938a0a65d36d7 Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 30 Jan 2023 19:36:24 +0545 Subject: [PATCH 32/77] 0.8.13 to 0.8.16 solidity version --- contracts/common/Address.sol | 2 +- contracts/common/Context.sol | 2 +- contracts/common/SafeERC20.sol | 2 +- contracts/common/SafeERC20Staking.sol | 2 +- contracts/common/Strings.sol | 2 +- contracts/common/access/AccessControl.sol | 2 +- contracts/common/access/IAccessControl.sol | 2 +- contracts/common/cryptography/ECDSA.sol | 2 +- contracts/common/cryptography/EIP712.sol | 2 +- contracts/common/introspection/ERC165.sol | 2 +- contracts/common/introspection/IERC165.sol | 2 +- contracts/common/math/BoringMath.sol | 2 +- contracts/common/math/Math.sol | 2 +- contracts/common/math/SafeCast.sol | 2 +- contracts/common/security/AdminPausable.sol | 2 +- contracts/common/security/IAdminPausable.sol | 2 +- contracts/common/security/Pausable.sol | 2 +- contracts/common/security/ReentrancyGuard.sol | 2 +- contracts/common/structs/Counters.sol | 2 +- contracts/common/structs/DoubleEndedQueue.sol | 2 +- contracts/common/structs/Timers.sol | 2 +- contracts/dao/governance/Governor.sol | 2 +- contracts/dao/governance/GovernorStructs.sol | 2 +- contracts/dao/governance/MainTokenGovernor.sol | 2 +- contracts/dao/governance/TimelockController.sol | 2 +- contracts/dao/governance/extensions/GovernorCountingSimple.sol | 2 +- contracts/dao/governance/extensions/GovernorSettings.sol | 2 +- contracts/dao/governance/extensions/GovernorTimelockControl.sol | 2 +- contracts/dao/governance/extensions/GovernorVotes.sol | 2 +- .../dao/governance/extensions/GovernorVotesQuorumFraction.sol | 2 +- contracts/dao/governance/extensions/IGovernorTimelock.sol | 2 +- contracts/dao/governance/extensions/IVotes.sol | 2 +- contracts/dao/governance/interfaces/IGovernor.sol | 2 +- contracts/dao/governance/interfaces/ITimelockController.sol | 2 +- contracts/dao/staking/StakingStorage.sol | 2 +- contracts/dao/staking/StakingStructs.sol | 2 +- contracts/dao/staking/helpers/IStakingGetterHelper.sol | 2 +- contracts/dao/staking/helpers/IStakingHelper.sol | 2 +- contracts/dao/staking/helpers/StakingGettersHelper.sol | 2 +- contracts/dao/staking/interfaces/IStaking.sol | 2 +- contracts/dao/staking/interfaces/IStakingEvents.sol | 2 +- contracts/dao/staking/interfaces/IStakingGetter.sol | 2 +- contracts/dao/staking/interfaces/IStakingHandler.sol | 2 +- contracts/dao/staking/interfaces/IStakingStorage.sol | 2 +- contracts/dao/staking/library/RewardsLibrary.sol | 2 +- contracts/dao/staking/library/StakingLibrary.sol | 2 +- contracts/dao/staking/packages/RewardsCalculator.sol | 2 +- contracts/dao/staking/packages/RewardsInternals.sol | 2 +- contracts/dao/staking/packages/StakingGetters.sol | 2 +- contracts/dao/staking/packages/StakingHandler.sol | 2 +- contracts/dao/staking/packages/StakingInternals.sol | 2 +- contracts/dao/staking/packages/StakingPackage.sol | 2 +- contracts/dao/staking/vault/interfaces/IVault.sol | 2 +- contracts/dao/staking/vault/interfaces/IVaultEvents.sol | 2 +- contracts/dao/staking/vault/packages/VaultPackage.sol | 2 +- contracts/dao/test/Box.sol | 2 +- contracts/dao/test/ERC20Rewards1.sol | 2 +- contracts/dao/test/ERC20Rewards2.sol | 2 +- contracts/dao/test/IBox.sol | 2 +- contracts/dao/test/Ownable.sol | 2 +- contracts/dao/test/staking/upgrades/StakingUpgrade.sol | 2 +- contracts/dao/test/staking/upgrades/VaultUpgrade.sol | 2 +- contracts/dao/test/token-factory/ERC20Factory.sol | 2 +- contracts/dao/test/token-factory/interfaces/IERC20Factory.sol | 2 +- contracts/dao/test/token-timelock/TokenTimelock.sol | 2 +- contracts/dao/test/token-timelock/TokenTimelockFactory.sol | 2 +- contracts/dao/test/token-timelock/interfaces/ITokenTimelock.sol | 2 +- .../test/token-timelock/interfaces/ITokenTimelockFactory.sol | 2 +- contracts/dao/tokens/ERC20/ERC20.sol | 2 +- contracts/dao/tokens/ERC20/IERC20.sol | 2 +- contracts/dao/tokens/ERC20/extensions/ERC20Permit.sol | 2 +- contracts/dao/tokens/ERC20/extensions/ERC20Votes.sol | 2 +- contracts/dao/tokens/ERC20/extensions/IERC20Metadata.sol | 2 +- contracts/dao/tokens/ERC20/extensions/IERC20Permit.sol | 2 +- contracts/dao/tokens/IVMainToken.sol | 2 +- contracts/dao/tokens/MainToken.sol | 2 +- contracts/dao/tokens/VMainToken.sol | 2 +- contracts/dao/treasury/MultiSigWallet.sol | 2 +- contracts/dao/treasury/interfaces/IMultiSigWallet.sol | 2 +- 79 files changed, 79 insertions(+), 79 deletions(-) diff --git a/contracts/common/Address.sol b/contracts/common/Address.sol index e0fb54e..dd23940 100644 --- a/contracts/common/Address.sol +++ b/contracts/common/Address.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /** * @dev Collection of functions related to the address type diff --git a/contracts/common/Context.sol b/contracts/common/Context.sol index 63aac0f..9c9a4dd 100644 --- a/contracts/common/Context.sol +++ b/contracts/common/Context.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (utils/Context.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /** * @dev Provides information about the current execution context, including the diff --git a/contracts/common/SafeERC20.sol b/contracts/common/SafeERC20.sol index 116dce6..952c224 100644 --- a/contracts/common/SafeERC20.sol +++ b/contracts/common/SafeERC20.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../dao/tokens/ERC20/IERC20.sol"; import "../dao/tokens/ERC20/extensions/IERC20Permit.sol"; diff --git a/contracts/common/SafeERC20Staking.sol b/contracts/common/SafeERC20Staking.sol index b9d0fa1..841b87d 100644 --- a/contracts/common/SafeERC20Staking.sol +++ b/contracts/common/SafeERC20Staking.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol) -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../dao/tokens/ERC20/IERC20.sol"; import "../dao/tokens/ERC20/extensions/IERC20Permit.sol"; diff --git a/contracts/common/Strings.sol b/contracts/common/Strings.sol index ca9fc15..2ff7606 100644 --- a/contracts/common/Strings.sol +++ b/contracts/common/Strings.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /** * @dev String operations. diff --git a/contracts/common/access/AccessControl.sol b/contracts/common/access/AccessControl.sol index 077864d..e0b51ca 100644 --- a/contracts/common/access/AccessControl.sol +++ b/contracts/common/access/AccessControl.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./IAccessControl.sol"; import "../Context.sol"; diff --git a/contracts/common/access/IAccessControl.sol b/contracts/common/access/IAccessControl.sol index f1cc593..8f5c3e6 100644 --- a/contracts/common/access/IAccessControl.sol +++ b/contracts/common/access/IAccessControl.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /** * @dev External interface of AccessControl declared to support ERC165 detection. diff --git a/contracts/common/cryptography/ECDSA.sol b/contracts/common/cryptography/ECDSA.sol index 5b490a3..ec3d38f 100644 --- a/contracts/common/cryptography/ECDSA.sol +++ b/contracts/common/cryptography/ECDSA.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../Strings.sol"; diff --git a/contracts/common/cryptography/EIP712.sol b/contracts/common/cryptography/EIP712.sol index cc8f0dd..42352fd 100644 --- a/contracts/common/cryptography/EIP712.sol +++ b/contracts/common/cryptography/EIP712.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (utils/cryptography/EIP712.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./ECDSA.sol"; diff --git a/contracts/common/introspection/ERC165.sol b/contracts/common/introspection/ERC165.sol index 041811a..f77626c 100644 --- a/contracts/common/introspection/ERC165.sol +++ b/contracts/common/introspection/ERC165.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./IERC165.sol"; diff --git a/contracts/common/introspection/IERC165.sol b/contracts/common/introspection/IERC165.sol index a66f7ab..12d699b 100644 --- a/contracts/common/introspection/IERC165.sol +++ b/contracts/common/introspection/IERC165.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /** * @dev Interface of the ERC165 standard, as defined in the diff --git a/contracts/common/math/BoringMath.sol b/contracts/common/math/BoringMath.sol index 5c0c33c..d998e8a 100644 --- a/contracts/common/math/BoringMath.sol +++ b/contracts/common/math/BoringMath.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /// @notice A library for performing overflow-/underflow-safe math, /// updated with awesomeness from of DappHub (https://github.com/dapphub/ds-math). diff --git a/contracts/common/math/Math.sol b/contracts/common/math/Math.sol index 2bb4231..84700b1 100644 --- a/contracts/common/math/Math.sol +++ b/contracts/common/math/Math.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Original Copyright 2016-2020 zOS Global Limited // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /** * @dev Standard math utilities missing in the Solidity language. diff --git a/contracts/common/math/SafeCast.sol b/contracts/common/math/SafeCast.sol index e172273..8883662 100644 --- a/contracts/common/math/SafeCast.sol +++ b/contracts/common/math/SafeCast.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (utils/math/SafeCast.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow diff --git a/contracts/common/security/AdminPausable.sol b/contracts/common/security/AdminPausable.sol index cd9ea24..7a50eb3 100644 --- a/contracts/common/security/AdminPausable.sol +++ b/contracts/common/security/AdminPausable.sol @@ -2,7 +2,7 @@ // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./IAdminPausable.sol"; import "@openzeppelin/contracts-upgradeable/access/AccessControlUpgradeable.sol"; diff --git a/contracts/common/security/IAdminPausable.sol b/contracts/common/security/IAdminPausable.sol index 04dc153..51ab66f 100644 --- a/contracts/common/security/IAdminPausable.sol +++ b/contracts/common/security/IAdminPausable.sol @@ -2,7 +2,7 @@ // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IAdminPausable { function adminPause(uint256 flags) external; diff --git a/contracts/common/security/Pausable.sol b/contracts/common/security/Pausable.sol index 07cb3d1..8f346f9 100644 --- a/contracts/common/security/Pausable.sol +++ b/contracts/common/security/Pausable.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../Context.sol"; diff --git a/contracts/common/security/ReentrancyGuard.sol b/contracts/common/security/ReentrancyGuard.sol index aa09d51..1c29a24 100644 --- a/contracts/common/security/ReentrancyGuard.sol +++ b/contracts/common/security/ReentrancyGuard.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /** * @dev Contract module that helps prevent reentrant calls to a function. diff --git a/contracts/common/structs/Counters.sol b/contracts/common/structs/Counters.sol index d32fbf0..6ce5692 100644 --- a/contracts/common/structs/Counters.sol +++ b/contracts/common/structs/Counters.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (utils/Counters.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /** * @title Counters diff --git a/contracts/common/structs/DoubleEndedQueue.sol b/contracts/common/structs/DoubleEndedQueue.sol index 4bc158f..373fde4 100644 --- a/contracts/common/structs/DoubleEndedQueue.sol +++ b/contracts/common/structs/DoubleEndedQueue.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.6.0) (utils/structs/DoubleEndedQueue.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../math/SafeCast.sol"; diff --git a/contracts/common/structs/Timers.sol b/contracts/common/structs/Timers.sol index b0b8366..b9ce975 100644 --- a/contracts/common/structs/Timers.sol +++ b/contracts/common/structs/Timers.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (utils/Timers.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; /** * @dev Tooling for timepoints, timers and delays diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 043b521..bd2bcff 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (governance/Governor.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../../common/cryptography/ECDSA.sol"; import "../../common/cryptography/EIP712.sol"; diff --git a/contracts/dao/governance/GovernorStructs.sol b/contracts/dao/governance/GovernorStructs.sol index 8097e5b..0d6d08a 100644 --- a/contracts/dao/governance/GovernorStructs.sol +++ b/contracts/dao/governance/GovernorStructs.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (governance/IGovernor.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../../common/structs/Timers.sol"; diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index 9b72918..64b1a72 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./Governor.sol"; import "./extensions/GovernorSettings.sol"; diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index 9a6c4ca..6347502 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (governance/TimelockController.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../../common/access/AccessControl.sol"; import "../../common/Address.sol"; diff --git a/contracts/dao/governance/extensions/GovernorCountingSimple.sol b/contracts/dao/governance/extensions/GovernorCountingSimple.sol index 05cd0c1..640ba8b 100644 --- a/contracts/dao/governance/extensions/GovernorCountingSimple.sol +++ b/contracts/dao/governance/extensions/GovernorCountingSimple.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorCountingSimple.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../Governor.sol"; diff --git a/contracts/dao/governance/extensions/GovernorSettings.sol b/contracts/dao/governance/extensions/GovernorSettings.sol index abb3eea..3d1bb67 100644 --- a/contracts/dao/governance/extensions/GovernorSettings.sol +++ b/contracts/dao/governance/extensions/GovernorSettings.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (governance/extensions/GovernorSettings.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../Governor.sol"; diff --git a/contracts/dao/governance/extensions/GovernorTimelockControl.sol b/contracts/dao/governance/extensions/GovernorTimelockControl.sol index ec6936b..8b0c5b7 100644 --- a/contracts/dao/governance/extensions/GovernorTimelockControl.sol +++ b/contracts/dao/governance/extensions/GovernorTimelockControl.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorTimelockControl.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./IGovernorTimelock.sol"; import "../Governor.sol"; diff --git a/contracts/dao/governance/extensions/GovernorVotes.sol b/contracts/dao/governance/extensions/GovernorVotes.sol index b6b16ed..24420d9 100644 --- a/contracts/dao/governance/extensions/GovernorVotes.sol +++ b/contracts/dao/governance/extensions/GovernorVotes.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.6.0) (governance/extensions/GovernorVotes.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../Governor.sol"; import "../extensions/IVotes.sol"; diff --git a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol b/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol index 0573b68..05af064 100644 --- a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol +++ b/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol @@ -3,7 +3,7 @@ // (governance/extensions/GovernorVotesQuorumFraction.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./GovernorVotes.sol"; diff --git a/contracts/dao/governance/extensions/IGovernorTimelock.sol b/contracts/dao/governance/extensions/IGovernorTimelock.sol index ec3b7eb..68a2dbf 100644 --- a/contracts/dao/governance/extensions/IGovernorTimelock.sol +++ b/contracts/dao/governance/extensions/IGovernorTimelock.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (governance/extensions/IGovernorTimelock.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../interfaces/IGovernor.sol"; diff --git a/contracts/dao/governance/extensions/IVotes.sol b/contracts/dao/governance/extensions/IVotes.sol index 76c3c78..9e89bd9 100644 --- a/contracts/dao/governance/extensions/IVotes.sol +++ b/contracts/dao/governance/extensions/IVotes.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.5.0) (governance/utils/IVotes.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IVotes { event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); diff --git a/contracts/dao/governance/interfaces/IGovernor.sol b/contracts/dao/governance/interfaces/IGovernor.sol index 1299790..eb3b6da 100644 --- a/contracts/dao/governance/interfaces/IGovernor.sol +++ b/contracts/dao/governance/interfaces/IGovernor.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (governance/IGovernor.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../GovernorStructs.sol"; import "../../../common/introspection/ERC165.sol"; diff --git a/contracts/dao/governance/interfaces/ITimelockController.sol b/contracts/dao/governance/interfaces/ITimelockController.sol index c6f9429..b6c844a 100644 --- a/contracts/dao/governance/interfaces/ITimelockController.sol +++ b/contracts/dao/governance/interfaces/ITimelockController.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface ITimelockController { function initialize( diff --git a/contracts/dao/staking/StakingStorage.sol b/contracts/dao/staking/StakingStorage.sol index 0876015..56020ee 100644 --- a/contracts/dao/staking/StakingStorage.sol +++ b/contracts/dao/staking/StakingStorage.sol @@ -2,7 +2,7 @@ // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./interfaces/IStakingStorage.sol"; import "./library/StakingLibrary.sol"; diff --git a/contracts/dao/staking/StakingStructs.sol b/contracts/dao/staking/StakingStructs.sol index b1c59ad..2e407b4 100644 --- a/contracts/dao/staking/StakingStructs.sol +++ b/contracts/dao/staking/StakingStructs.sol @@ -2,7 +2,7 @@ // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; enum StreamStatus { INACTIVE, diff --git a/contracts/dao/staking/helpers/IStakingGetterHelper.sol b/contracts/dao/staking/helpers/IStakingGetterHelper.sol index fa30122..99506fc 100644 --- a/contracts/dao/staking/helpers/IStakingGetterHelper.sol +++ b/contracts/dao/staking/helpers/IStakingGetterHelper.sol @@ -1,6 +1,6 @@ // Copyright SECURRENCY INC. // SPDX-License-Identifier: AGPL 3.0 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStructs.sol"; import "../interfaces/IStakingGetter.sol"; diff --git a/contracts/dao/staking/helpers/IStakingHelper.sol b/contracts/dao/staking/helpers/IStakingHelper.sol index d4e5a5a..fe0e212 100644 --- a/contracts/dao/staking/helpers/IStakingHelper.sol +++ b/contracts/dao/staking/helpers/IStakingHelper.sol @@ -1,6 +1,6 @@ // Copyright SECURRENCY INC. // SPDX-License-Identifier: AGPL 3.0 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStructs.sol"; import "../interfaces/IStakingGetter.sol"; diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index 8bbee53..09940d6 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -1,6 +1,6 @@ // Copyright SECURRENCY INC. // SPDX-License-Identifier: AGPL 3.0 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./IStakingHelper.sol"; import "./IStakingGetterHelper.sol"; diff --git a/contracts/dao/staking/interfaces/IStaking.sol b/contracts/dao/staking/interfaces/IStaking.sol index 855111e..e1aa6ff 100644 --- a/contracts/dao/staking/interfaces/IStaking.sol +++ b/contracts/dao/staking/interfaces/IStaking.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStructs.sol"; import "./IStakingGetter.sol"; diff --git a/contracts/dao/staking/interfaces/IStakingEvents.sol b/contracts/dao/staking/interfaces/IStakingEvents.sol index 754b779..07d11f6 100644 --- a/contracts/dao/staking/interfaces/IStakingEvents.sol +++ b/contracts/dao/staking/interfaces/IStakingEvents.sol @@ -2,7 +2,7 @@ // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IStakingEvents { event Staked(address indexed account, uint256 amount, uint256 streamShares, uint256 nVoteToken, uint256 indexed lockId, uint256 end); diff --git a/contracts/dao/staking/interfaces/IStakingGetter.sol b/contracts/dao/staking/interfaces/IStakingGetter.sol index 2166fdd..e1d786a 100644 --- a/contracts/dao/staking/interfaces/IStakingGetter.sol +++ b/contracts/dao/staking/interfaces/IStakingGetter.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStructs.sol"; diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index 8c77d46..a2629c6 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStructs.sol"; import "./IStakingGetter.sol"; diff --git a/contracts/dao/staking/interfaces/IStakingStorage.sol b/contracts/dao/staking/interfaces/IStakingStorage.sol index 173facd..f24bd09 100644 --- a/contracts/dao/staking/interfaces/IStakingStorage.sol +++ b/contracts/dao/staking/interfaces/IStakingStorage.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStructs.sol"; diff --git a/contracts/dao/staking/library/RewardsLibrary.sol b/contracts/dao/staking/library/RewardsLibrary.sol index e5d9a54..c5c34f4 100644 --- a/contracts/dao/staking/library/RewardsLibrary.sol +++ b/contracts/dao/staking/library/RewardsLibrary.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStructs.sol"; import "../../../common/math/FullMath.sol"; diff --git a/contracts/dao/staking/library/StakingLibrary.sol b/contracts/dao/staking/library/StakingLibrary.sol index 3fddb2e..ac6554e 100644 --- a/contracts/dao/staking/library/StakingLibrary.sol +++ b/contracts/dao/staking/library/StakingLibrary.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStructs.sol"; diff --git a/contracts/dao/staking/packages/RewardsCalculator.sol b/contracts/dao/staking/packages/RewardsCalculator.sol index bd261e5..473ab4a 100644 --- a/contracts/dao/staking/packages/RewardsCalculator.sol +++ b/contracts/dao/staking/packages/RewardsCalculator.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStructs.sol"; import "../interfaces/IRewardsHandler.sol"; import "../../../common/math/FullMath.sol"; diff --git a/contracts/dao/staking/packages/RewardsInternals.sol b/contracts/dao/staking/packages/RewardsInternals.sol index c82049b..abcb775 100644 --- a/contracts/dao/staking/packages/RewardsInternals.sol +++ b/contracts/dao/staking/packages/RewardsInternals.sol @@ -2,7 +2,7 @@ // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStorage.sol"; import "../interfaces/IStakingEvents.sol"; import "../interfaces/IRewardsHandler.sol"; diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index 15ee56c..8322f22 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -2,7 +2,7 @@ // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../StakingStorage.sol"; import "../interfaces/IStakingGetter.sol"; diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 61f63fc..0ebdde7 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -2,7 +2,7 @@ // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./StakingInternals.sol"; import "../StakingStorage.sol"; diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 928c015..d049332 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -2,7 +2,7 @@ // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./RewardsInternals.sol"; import "../interfaces/IStakingEvents.sol"; diff --git a/contracts/dao/staking/packages/StakingPackage.sol b/contracts/dao/staking/packages/StakingPackage.sol index d829279..ffc9d79 100644 --- a/contracts/dao/staking/packages/StakingPackage.sol +++ b/contracts/dao/staking/packages/StakingPackage.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./StakingHandler.sol"; import "./StakingGetters.sol"; diff --git a/contracts/dao/staking/vault/interfaces/IVault.sol b/contracts/dao/staking/vault/interfaces/IVault.sol index 28ce113..26f23c8 100644 --- a/contracts/dao/staking/vault/interfaces/IVault.sol +++ b/contracts/dao/staking/vault/interfaces/IVault.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: AGPL-3.0 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IVault { function initVault(address _admin, address[] calldata supportedTokens) external; diff --git a/contracts/dao/staking/vault/interfaces/IVaultEvents.sol b/contracts/dao/staking/vault/interfaces/IVaultEvents.sol index b69dcbb..d71909f 100644 --- a/contracts/dao/staking/vault/interfaces/IVaultEvents.sol +++ b/contracts/dao/staking/vault/interfaces/IVaultEvents.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IVaultEvents { event TokenAdded(address indexed tokenAddress, address indexed addedBy, uint256 timestamp); diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index 0c486ba..6a5baa7 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -2,7 +2,7 @@ // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../interfaces/IVault.sol"; import "../interfaces/IVaultEvents.sol"; import "../../../tokens/ERC20/IERC20.sol"; diff --git a/contracts/dao/test/Box.sol b/contracts/dao/test/Box.sol index 9d33491..63aaa42 100644 --- a/contracts/dao/test/Box.sol +++ b/contracts/dao/test/Box.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./Ownable.sol"; import "./IBox.sol"; diff --git a/contracts/dao/test/ERC20Rewards1.sol b/contracts/dao/test/ERC20Rewards1.sol index e422c7e..af025a8 100644 --- a/contracts/dao/test/ERC20Rewards1.sol +++ b/contracts/dao/test/ERC20Rewards1.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../tokens/ERC20/IERC20.sol"; import "../tokens/ERC20/extensions/IERC20Metadata.sol"; diff --git a/contracts/dao/test/ERC20Rewards2.sol b/contracts/dao/test/ERC20Rewards2.sol index 44955a3..8562b48 100644 --- a/contracts/dao/test/ERC20Rewards2.sol +++ b/contracts/dao/test/ERC20Rewards2.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../tokens/ERC20/IERC20.sol"; import "../tokens/ERC20/extensions/IERC20Metadata.sol"; diff --git a/contracts/dao/test/IBox.sol b/contracts/dao/test/IBox.sol index 34cc602..1e07bce 100644 --- a/contracts/dao/test/IBox.sol +++ b/contracts/dao/test/IBox.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IBox { // Emitted when the stored value changes diff --git a/contracts/dao/test/Ownable.sol b/contracts/dao/test/Ownable.sol index fee6e00..5b9e6e2 100644 --- a/contracts/dao/test/Ownable.sol +++ b/contracts/dao/test/Ownable.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../../common/Context.sol"; diff --git a/contracts/dao/test/staking/upgrades/StakingUpgrade.sol b/contracts/dao/test/staking/upgrades/StakingUpgrade.sol index 146d631..7ec6927 100644 --- a/contracts/dao/test/staking/upgrades/StakingUpgrade.sol +++ b/contracts/dao/test/staking/upgrades/StakingUpgrade.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../../../staking/packages/StakingHandler.sol"; diff --git a/contracts/dao/test/staking/upgrades/VaultUpgrade.sol b/contracts/dao/test/staking/upgrades/VaultUpgrade.sol index ffc6bbf..a9ba41d 100644 --- a/contracts/dao/test/staking/upgrades/VaultUpgrade.sol +++ b/contracts/dao/test/staking/upgrades/VaultUpgrade.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: AGPL 3.0 // Original Copyright Aurora // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../../../staking/vault/packages/VaultPackage.sol"; diff --git a/contracts/dao/test/token-factory/ERC20Factory.sol b/contracts/dao/test/token-factory/ERC20Factory.sol index 0bb94ed..9ef6c05 100644 --- a/contracts/dao/test/token-factory/ERC20Factory.sol +++ b/contracts/dao/test/token-factory/ERC20Factory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./interfaces/IERC20Factory.sol"; import "../../tokens/ERC20/ERC20.sol"; diff --git a/contracts/dao/test/token-factory/interfaces/IERC20Factory.sol b/contracts/dao/test/token-factory/interfaces/IERC20Factory.sol index 0286e3b..36efced 100644 --- a/contracts/dao/test/token-factory/interfaces/IERC20Factory.sol +++ b/contracts/dao/test/token-factory/interfaces/IERC20Factory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IERC20Factory { function deployToken( diff --git a/contracts/dao/test/token-timelock/TokenTimelock.sol b/contracts/dao/test/token-timelock/TokenTimelock.sol index 6f65dc9..9a62734 100644 --- a/contracts/dao/test/token-timelock/TokenTimelock.sol +++ b/contracts/dao/test/token-timelock/TokenTimelock.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/utils/TokenTimelock.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../../../common/SafeERC20.sol"; import "./interfaces/ITokenTimelock.sol"; diff --git a/contracts/dao/test/token-timelock/TokenTimelockFactory.sol b/contracts/dao/test/token-timelock/TokenTimelockFactory.sol index 55f5380..6f709c4 100644 --- a/contracts/dao/test/token-timelock/TokenTimelockFactory.sol +++ b/contracts/dao/test/token-timelock/TokenTimelockFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./TokenTimelock.sol"; import "./interfaces/ITokenTimelockFactory.sol"; diff --git a/contracts/dao/test/token-timelock/interfaces/ITokenTimelock.sol b/contracts/dao/test/token-timelock/interfaces/ITokenTimelock.sol index d5a811e..94b7a3f 100644 --- a/contracts/dao/test/token-timelock/interfaces/ITokenTimelock.sol +++ b/contracts/dao/test/token-timelock/interfaces/ITokenTimelock.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/utils/TokenTimelock.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../../../../common/SafeERC20.sol"; diff --git a/contracts/dao/test/token-timelock/interfaces/ITokenTimelockFactory.sol b/contracts/dao/test/token-timelock/interfaces/ITokenTimelockFactory.sol index a64ed10..54dfa96 100644 --- a/contracts/dao/test/token-timelock/interfaces/ITokenTimelockFactory.sol +++ b/contracts/dao/test/token-timelock/interfaces/ITokenTimelockFactory.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface ITokenTimelockFactory { function deployTokenTimelocks(address[] calldata beneficiaries, uint256[] calldata releaseTimes) external returns (address[] memory); diff --git a/contracts/dao/tokens/ERC20/ERC20.sol b/contracts/dao/tokens/ERC20/ERC20.sol index 04bb6de..53e07ce 100644 --- a/contracts/dao/tokens/ERC20/ERC20.sol +++ b/contracts/dao/tokens/ERC20/ERC20.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/ERC20.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./IERC20.sol"; import "./extensions/IERC20Metadata.sol"; diff --git a/contracts/dao/tokens/ERC20/IERC20.sol b/contracts/dao/tokens/ERC20/IERC20.sol index 68a32d6..7476ba8 100644 --- a/contracts/dao/tokens/ERC20/IERC20.sol +++ b/contracts/dao/tokens/ERC20/IERC20.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IERC20 { event Transfer(address indexed from, address indexed to, uint256 value); diff --git a/contracts/dao/tokens/ERC20/extensions/ERC20Permit.sol b/contracts/dao/tokens/ERC20/extensions/ERC20Permit.sol index 367b839..21c14f7 100644 --- a/contracts/dao/tokens/ERC20/extensions/ERC20Permit.sol +++ b/contracts/dao/tokens/ERC20/extensions/ERC20Permit.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/extensions/ERC20Permit.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./IERC20Permit.sol"; import "../ERC20.sol"; diff --git a/contracts/dao/tokens/ERC20/extensions/ERC20Votes.sol b/contracts/dao/tokens/ERC20/extensions/ERC20Votes.sol index 351e75d..e03c6dd 100644 --- a/contracts/dao/tokens/ERC20/extensions/ERC20Votes.sol +++ b/contracts/dao/tokens/ERC20/extensions/ERC20Votes.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/extensions/ERC20Votes.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./ERC20Permit.sol"; import "../../../governance/extensions/IVotes.sol"; diff --git a/contracts/dao/tokens/ERC20/extensions/IERC20Metadata.sol b/contracts/dao/tokens/ERC20/extensions/IERC20Metadata.sol index 1c645f3..1af17b0 100644 --- a/contracts/dao/tokens/ERC20/extensions/IERC20Metadata.sol +++ b/contracts/dao/tokens/ERC20/extensions/IERC20Metadata.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../IERC20.sol"; diff --git a/contracts/dao/tokens/ERC20/extensions/IERC20Permit.sol b/contracts/dao/tokens/ERC20/extensions/IERC20Permit.sol index c6a5569..8e87e34 100644 --- a/contracts/dao/tokens/ERC20/extensions/IERC20Permit.sol +++ b/contracts/dao/tokens/ERC20/extensions/IERC20Permit.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Permit.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IERC20Permit { function permit( diff --git a/contracts/dao/tokens/IVMainToken.sol b/contracts/dao/tokens/IVMainToken.sol index b49e1ae..12d8d7c 100644 --- a/contracts/dao/tokens/IVMainToken.sol +++ b/contracts/dao/tokens/IVMainToken.sol @@ -2,7 +2,7 @@ // Original Copyright OpenZeppelin Contracts (last updated v4.7.0) (governance/IGovernor.sol) // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IVMainToken { event MemberAddedToWhitelist(address _member); diff --git a/contracts/dao/tokens/MainToken.sol b/contracts/dao/tokens/MainToken.sol index 85aafb5..f3b8072 100644 --- a/contracts/dao/tokens/MainToken.sol +++ b/contracts/dao/tokens/MainToken.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./ERC20/ERC20.sol"; diff --git a/contracts/dao/tokens/VMainToken.sol b/contracts/dao/tokens/VMainToken.sol index 6993442..c5817dd 100644 --- a/contracts/dao/tokens/VMainToken.sol +++ b/contracts/dao/tokens/VMainToken.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "../../common/security/Pausable.sol"; import "../../common/access/AccessControl.sol"; diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 570f0c2..dde2336 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; import "./interfaces/IMultiSigWallet.sol"; import "../../common/Address.sol"; diff --git a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol index ef53bb6..80a82f9 100644 --- a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol +++ b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: MIT // Copyright Fathom 2022 -pragma solidity 0.8.13; +pragma solidity 0.8.16; interface IMultiSigWallet { event Deposit(address indexed sender, uint256 amount, uint256 balance); From a073d34cee65913cb317b0058f504f4fa135093b Mon Sep 17 00:00:00 2001 From: ssubik Date: Tue, 31 Jan 2023 12:34:07 +0545 Subject: [PATCH 33/77] loop fix --- contracts/dao/treasury/MultiSigWallet.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index dde2336..dbd57c9 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -254,7 +254,7 @@ contract MultiSigWallet is IMultiSigWallet { transaction.numConfirmations -= 1; isConfirmed[_txIndex][msg.sender] = false; - for (uint256 i = 0; i < confirmedTransactions[msg.sender].length - 1; i++) + for (uint256 i = 0; i < confirmedTransactions[msg.sender].length; i++) if (confirmedTransactions[msg.sender][i] == _txIndex) { confirmedTransactions[msg.sender][i] = confirmedTransactions[msg.sender][confirmedTransactions[msg.sender].length - 1]; From f0cb38ccc0cae5919ae912b75862afa30181eb3b Mon Sep 17 00:00:00 2001 From: ssubik Date: Tue, 31 Jan 2023 17:11:52 +0545 Subject: [PATCH 34/77] making enumerable library --- audit-report/Fathom_DAO-review.md | 17 ++++--- .../staking/helpers/StakingGettersHelper.sol | 1 + .../dao/staking/packages/StakingGetters.sol | 1 - contracts/dao/treasury/MultiSigWallet.sol | 49 +++++++++---------- .../treasury/interfaces/IMultiSigWallet.sol | 1 + 5 files changed, 34 insertions(+), 35 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 8045928..345518b 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -143,7 +143,7 @@ Implemented Auditors Recommendation. with slight change: changeRequirement(numConfirmationsRequired + _owners.length); ``` -#### 1. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE -ASK MAXJI - ask auditor, does it require to revoke confirmation in submitTransaction] +#### 1. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE -ASK Anton - ask auditor, does it require to revoke confirmation in submitTransaction] ##### Description In the function [`removeOwner`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L96) the owner is being removed without revocation of transaction signatures, where they've signed. This creates a situation where the signatures of non-existent owners may be used. For example, like in the following scenario: @@ -394,7 +394,7 @@ But it should be noted that `addToWhitelist` and `removeFromWhitelist` can be ca We recommend refactoring this code and adding internal functions `_addToWhitelist` and `_removeFromWhitelist` without access control to `grantMinterRole` and `revokeMinterRole`. -#### 3. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[NOTDONE-CHECK] +#### 3. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[DONE, Ask Anton] ##### Description In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. ##### Recommendation @@ -487,7 +487,7 @@ We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppeli ###### Fathom's response Implemented Auditors Recommendation. -#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE-AskAnton] +#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE] ##### Description In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. @@ -781,7 +781,7 @@ We recommend removing `Governance` from this modifier and give the permission to ###### Fathom's response Thats the way its designed -#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[NOTDONE -CHECK AGAIN] +#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[DONE] ##### Description In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. Based on the logic of the contract, there may be the following cases: @@ -845,7 +845,7 @@ In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom- ##### Recommendation We recommend adding balance check while adding a transaction with a non-zero value `_value`. -#### [NEW] There is no time limit for executing proposal in `Governor`[Ask MAXJI -DONE] +#### [NEW] There is no time limit for executing proposal in `Governor`[Ask ANTON -DONE] ##### Description The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract has no parameters for the time limit on `proposal` execution. This can result in no longer relevant proposal being executed after a period of time. ##### Recommendation @@ -881,7 +881,7 @@ require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Go ###### Fathom's response Implemented Auditors Recommendation. -#### 17. [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[DONE Check again] +#### 17. [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[DONE] ##### Description In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) contracts the `execute` functions do not check the `msg.value` balance value needed to execute `_targets`, which would result in gas consumption even if the amount of `ETH` is not enough. ##### Recommendation @@ -917,7 +917,7 @@ We recommend adding a check that `newProposalThreshold` is not zero. ###### Fathom's response Implemented Auditors Recommendation. -#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE, check again] +#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE, Ask Anton] ##### Description In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. ##### Recommendation @@ -932,6 +932,9 @@ We recommend adding a limit for pending proposals for one user. Ask Auditors -> This is not desired functionality to limit pending proposals for one user. +Make high enough proposalTimeDelay +If time, add a block for msg.sender + #### [FIXED] A missing check that tokens are on the balance when calling the `payRewards` function in the `VaultPackage` contract ##### Description In the `VaultPackage` contract when calling the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31) there is no processing of errors such as: diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index 09940d6..7de25ff 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -100,6 +100,7 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { return penalty; } + function _getAllLocks(address account) internal view returns(LockedBalance[] memory) { return IStakingHelper(stakingContract).getAllLocks(account); diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index 8322f22..26026df 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -49,5 +49,4 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { // streams[streamId].status // ); // } - } diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index dbd57c9..22d6668 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -6,9 +6,10 @@ pragma solidity 0.8.16; import "./interfaces/IMultiSigWallet.sol"; import "../../common/Address.sol"; import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; +import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; contract MultiSigWallet is IMultiSigWallet { using Address for address; - + using EnumerableSet for EnumerableSet.UintSet; struct Transaction { address to; bool executed; @@ -26,7 +27,6 @@ contract MultiSigWallet is IMultiSigWallet { address public governor; uint256 public numConfirmationsRequired; - uint256 public lastDisabledTransactionIndex; mapping(address => bool) public isOwner; mapping(uint256 => mapping(address => bool)) public isConfirmed; @@ -34,8 +34,7 @@ contract MultiSigWallet is IMultiSigWallet { mapping(address => bytes32) internal whitelistedBytesCode; Transaction[] public transactions; - mapping(address => uint256[]) confirmedTransactions; - + mapping(address => EnumerableSet.UintSet) internal confirmedTransactionsByOwner; modifier onlyOwnerOrGov() { require(isOwner[msg.sender] || governor == msg.sender, "MultiSig: MultiSigWallet, onlyOwnerOrGov(): Neither owner nor governor"); @@ -135,21 +134,19 @@ contract MultiSigWallet is IMultiSigWallet { owners.pop(); if (numConfirmationsRequired > owners.length) changeRequirement(owners.length); - - uint256 nConfirmedTxnByOwner = confirmedTransactions[owner].length; - if(nConfirmedTxnByOwner > 0){ - for(uint i = nConfirmedTxnByOwner; i >1; i--){ - uint256 _txIndex = confirmedTransactions[owner][i-1]; - Transaction storage transaction = transactions[_txIndex]; - transaction.numConfirmations -= 1; - isConfirmed[_txIndex][owner] = false; - confirmedTransactions[owner].pop(); - emit RevokeConfirmation(owner, _txIndex); - } + + uint256 nConfirmedTxnByOwner = confirmedTransactionsByOwner[owner].values().length; + + for(uint i = nConfirmedTxnByOwner; i >1; i--){ + uint256 _txIndex = confirmedTransactionsByOwner[owner].at(i-1); + Transaction storage transaction = transactions[_txIndex]; + transaction.numConfirmations -= 1; + isConfirmed[_txIndex][owner] = false; + confirmedTransactionsByOwner[owner].remove(_txIndex); + emit RevokeConfirmation(owner, _txIndex); } emit OwnerRemoval(owner); } - function addOwners(address[] memory _owners) public override @@ -213,7 +210,7 @@ contract MultiSigWallet is IMultiSigWallet { transaction.numConfirmations += 1; isConfirmed[_txIndex][msg.sender] = true; - confirmedTransactions[msg.sender].push(_txIndex); + confirmedTransactionsByOwner[msg.sender].add(_txIndex); emit ConfirmTransaction(msg.sender, _txIndex); } @@ -233,7 +230,13 @@ contract MultiSigWallet is IMultiSigWallet { require(transaction.numConfirmations >= numConfirmationsRequired, "cannot execute tx"); transaction.executed = true; - + + for(uint i = 0; i < owners.length;i++){ + if(confirmedTransactionsByOwner[owners[i]].contains(_txIndex)){ + confirmedTransactionsByOwner[owners[i]].remove(_txIndex); + } + + } (bool success, bytes memory data) = transaction.to.call{ value: transaction.value }(transaction.data); emit ExecuteTransaction(msg.sender, _txIndex,success, data); @@ -253,15 +256,7 @@ contract MultiSigWallet is IMultiSigWallet { transaction.numConfirmations -= 1; isConfirmed[_txIndex][msg.sender] = false; - - for (uint256 i = 0; i < confirmedTransactions[msg.sender].length; i++) - if (confirmedTransactions[msg.sender][i] == _txIndex) { - confirmedTransactions[msg.sender][i] - = confirmedTransactions[msg.sender][confirmedTransactions[msg.sender].length - 1]; - break; - } - confirmedTransactions[msg.sender].pop(); - + confirmedTransactionsByOwner[msg.sender].remove(_txIndex); emit RevokeConfirmation(msg.sender, _txIndex); } diff --git a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol index 80a82f9..9ad8d8a 100644 --- a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol +++ b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol @@ -2,6 +2,7 @@ // Copyright Fathom 2022 pragma solidity 0.8.16; +import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; interface IMultiSigWallet { event Deposit(address indexed sender, uint256 amount, uint256 balance); From 82016d332a192f118f67e1a173d3fe22d4d12655 Mon Sep 17 00:00:00 2001 From: ssubik Date: Tue, 31 Jan 2023 18:02:04 +0545 Subject: [PATCH 35/77] doing custom errors to reduce size --- .../dao/staking/interfaces/IStakingGetter.sol | 6 ++++ .../dao/staking/packages/RewardsInternals.sol | 6 ++-- .../dao/staking/packages/StakingGetters.sol | 26 +++++++-------- .../dao/staking/packages/StakingHandler.sol | 13 +++++--- .../dao/staking/packages/StakingInternals.sol | 32 +++++++++++++------ 5 files changed, 53 insertions(+), 30 deletions(-) diff --git a/contracts/dao/staking/interfaces/IStakingGetter.sol b/contracts/dao/staking/interfaces/IStakingGetter.sol index e1d786a..e0e6c2d 100644 --- a/contracts/dao/staking/interfaces/IStakingGetter.sol +++ b/contracts/dao/staking/interfaces/IStakingGetter.sol @@ -30,6 +30,12 @@ interface IStakingGetter { uint256 lockId ) external view returns (uint256); function readBySlot(uint256 slot) external view returns(bytes32); + function getStreamStatus(uint256 streamId) + external + view + returns ( + StreamStatus status + ); //function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); // function getStreamsCount() external view returns (uint256); diff --git a/contracts/dao/staking/packages/RewardsInternals.sol b/contracts/dao/staking/packages/RewardsInternals.sol index abcb775..9dd4007 100644 --- a/contracts/dao/staking/packages/RewardsInternals.sol +++ b/contracts/dao/staking/packages/RewardsInternals.sol @@ -12,7 +12,7 @@ contract RewardsInternals is StakingStorage, IStakingEvents { // solhint-disable not-rely-on-time function _updateStreamsRewardsSchedules(uint256 streamId, uint256 rewardTokenAmount) internal { uint256 streamScheduleRewardLength = streams[streamId].schedule.reward.length; - for (uint256 i = 0; i < streamScheduleRewardLength; i++) { + for (uint256 i; i < streamScheduleRewardLength; i++) { streams[streamId].schedule.reward[i] = FullMath.mulDiv(streams[streamId].schedule.reward[i], rewardTokenAmount, streams[streamId].maxDepositAmount); } } @@ -40,7 +40,7 @@ contract RewardsInternals is StakingStorage, IStakingEvents { function _moveAllStreamRewardsToPending(address account, uint256 lockId) internal { uint256 streamsLength = streams.length; - for (uint256 i = 0; i < streamsLength; i++) { + for (uint256 i; i < streamsLength; i++) { if (streams[i].status == StreamStatus.ACTIVE) _moveRewardsToPending(account, i, lockId); } } @@ -58,7 +58,7 @@ contract RewardsInternals is StakingStorage, IStakingEvents { function _updateStreamRPS() internal { if (touchedAt == block.timestamp) return; // Already updated by previous transaction if (totalAmountOfStakedToken != 0) { - for (uint256 i = 0; i < streams.length; i++) { + for (uint256 i; i < streams.length; i++) { if (streams[i].status == StreamStatus.ACTIVE) { streams[i].rps = _getLatestRewardsPerShare(i); } diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index 26026df..f837729 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -32,21 +32,19 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { value := sload(slot) } } - //TODO: Do by assembly in staking getter helper. Almost done function getAllLocks(address account) external override view returns (LockedBalance[] memory) { return locks[account]; } - //TODO: Do by assembly in staking getter helper. Almost done - // function getStreamStatus(uint256 streamId) - // external - // view - // override - // returns ( - // StreamStatus status - // ) - // { - // return ( - // streams[streamId].status - // ); - // } + function getStreamStatus(uint256 streamId) + external + view + override + returns ( + StreamStatus status + ) + { + return ( + streams[streamId].status + ); + } } diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 0ebdde7..c23a1a7 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -16,6 +16,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A using SafeERC20Staking for IERC20; bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); + error LockIdLengthExceeded(uint256 _lockId, address _account); constructor() { _disableInitializers(); @@ -179,7 +180,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function createLocksForCouncils(CreateLockParams[] calldata lockParams) public override onlyRole(DEFAULT_ADMIN_ROLE) { require(!councilsInitialized, "created"); councilsInitialized = true; - for (uint256 i = 0; i < lockParams.length; i++) { + for (uint256 i; i < lockParams.length; i++) { address account = lockParams[i].account; prohibitedEarlyWithdraw[account][locks[account].length + 1] = true; _createLock(lockParams[i].amount, lockParams[i].lockPeriod, account); @@ -220,7 +221,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } function claimAllStreamRewardsForLock(uint256 lockId) public override pausable(1) { - require(lockId <= locks[msg.sender].length, "bad lockid"); + if(lockId > locks[msg.sender].length){ + revert LockIdLengthExceeded(lockId, msg.sender); + } require(lockId != 0, "lockId 0"); _updateStreamRPS(); // Claim all streams while skipping inactive streams. @@ -242,7 +245,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function withdrawAllStreams() public override pausable(1) { User storage userAccount = users[msg.sender]; - for (uint256 i = 0; i < streams.length; i++) { + for (uint256 i; i < streams.length; i++) { if (userAccount.pendings[i] != 0 && block.timestamp > userAccount.releaseTime[i] && streams[i].status == StreamStatus.ACTIVE) { _withdraw(i); } @@ -292,7 +295,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function _verifyUnlock(uint256 lockId) internal view { require(lockId > 0, "zero lockid"); - require(lockId <= locks[msg.sender].length, "bad lockid"); + if(lockId > locks[msg.sender].length){ + revert LockIdLengthExceeded(lockId, msg.sender); + } LockedBalance storage lock = locks[msg.sender][lockId - 1]; require(lock.amountOfToken > 0, "no amount"); require(lock.owner == msg.sender, "bad owner"); diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index d049332..ccf8dcf 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -15,6 +15,9 @@ import "../../../common/math/FullMath.sol"; contract StakingInternals is RewardsInternals { // solhint-disable not-rely-on-time + error ZeroAddress(address _address); + error ZeroTotalAmountOfStakedToken(); + error ZeroAmountOfLockedToken(); function _initializeStaking( address _mainToken, address _voteToken, @@ -24,9 +27,15 @@ contract StakingInternals is RewardsInternals { uint256 _voteShareCoef, uint256 _voteLockCoef ) internal { - require(_mainToken != address(0x00), "main addr zero"); - require(_voteToken != address(0x00), "vote addr zero"); - require(_vault != address(0x00), "vault addr zero"); + if(_mainToken == address(0x00)){ + revert ZeroAddress(_mainToken); + } + if(_voteToken == address(0x00)){ + revert ZeroAddress(_voteToken); + } + if(_vault == address(0x00)){ + revert ZeroAddress(_vault); + } require(_weight.maxWeightShares > _weight.minWeightShares, "bad share"); require(_weight.maxWeightPenalty > _weight.minWeightPenalty, "bad penalty"); @@ -87,8 +96,13 @@ contract StakingInternals is RewardsInternals { ) internal { User storage userAccount = users[account]; LockedBalance storage updateLock = locks[account][lockId - 1]; - require(totalAmountOfStakedToken != 0, "Zero tokens"); - require(updateLock.amountOfToken != 0, "No token"); + if(totalAmountOfStakedToken == 0){ + revert ZeroTotalAmountOfStakedToken(); + } + + if(updateLock.amountOfToken == 0){ + revert ZeroAmountOfLockedToken(); + } uint256 nVoteToken = updateLock.amountOfVoteToken; /// if you unstake, early or partial or complete, /// the number of vote tokens for lock position is set to zero @@ -135,7 +149,7 @@ contract StakingInternals is RewardsInternals { lock.positionStreamShares += BoringMath.to128(weightedAmountOfSharesPerStream); uint256 streamsLength = streams.length; - for (uint256 i = 0; i < streamsLength; i++) { + for (uint256 i; i < streamsLength; i++) { if (streams[i].status == StreamStatus.ACTIVE) { userAccount.rpsDuringLastClaimForLock[lockId][i] = streams[i].rps; } @@ -187,7 +201,7 @@ contract StakingInternals is RewardsInternals { updateLock.positionStreamShares += BoringMath.to128(weightedAmountOfSharesPerStream); totalStreamShares += weightedAmountOfSharesPerStream; uint256 streamsLength = streams.length; - for (uint256 i = 0; i < streamsLength; i++) { + for (uint256 i; i < streamsLength; i++) { // The new shares should not claim old rewards if (streams[i].status == StreamStatus.ACTIVE) { userAccount.rpsDuringLastClaimForLock[lockId][i] = streams[i].rps; @@ -227,11 +241,11 @@ contract StakingInternals is RewardsInternals { if (lastLockId != lockId && lastLockId > 1) { LockedBalance storage lastIndexLockedBalance = locks[account][lastLockId - 1]; locks[account][lockId - 1] = lastIndexLockedBalance; - for (uint256 i = 0; i < streamsLength; i++) { + for (uint256 i; i < streamsLength; i++) { userAccount.rpsDuringLastClaimForLock[lockId][i] = userAccount.rpsDuringLastClaimForLock[lastLockId][i]; } } - for (uint256 i = 0; i < streamsLength; i++) { + for (uint256 i; i < streamsLength; i++) { delete userAccount.rpsDuringLastClaimForLock[lastLockId][i]; } locks[account].pop(); From d4d24f915ef82da92cb55235a488e12c1759b0fc Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 1 Feb 2023 12:37:29 +0545 Subject: [PATCH 36/77] lifetime audit fix for multisig --- audit-report/Fathom_DAO-review.md | 8 ++++---- contracts/dao/staking/packages/StakingHandler.sol | 6 +++--- contracts/dao/treasury/MultiSigWallet.sol | 9 ++++----- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 345518b..d210b10 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -256,8 +256,8 @@ modifier validRequirement(uint ownerCount, uint _required) { } ``` -#### 2. [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet` -##### Description[NOTDONE - CHECKAGAIN -ASK MAXJI] +#### [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet`[DONE -ASK AUDITOR] +##### Description In the structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) there's no lifetime parameter `expired`, which is responsible for the period of time during which the transaction must be executed. Since transactions may be executed at random time and are not removed over time, frozen, previously not approved transactions can be executed after a certain time and cause an undesirable effect. ##### Recommendation We recommend adding an individual parameter, which is responsible for the maximum time until the transaction can be executed, e.g. `expired` and check it before running transactions. @@ -272,7 +272,7 @@ We meant the `lifetime` parameter, which is passed as a function parameter. `transactions[_txIndex].expireTimestamp = block.timestamp + lifetime` -#### 5. [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[DONE] +#### 5. [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[DONE -ASK AUDITOR] ##### Description In the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, Governance can take away the `TIMELOCK_ADMIN_ROLE` rights from the address `admin`. In the case of an attack on `Governance` and `Council` this would make it impossible to revoke the role from the captured contracts. ##### Recommendation @@ -303,7 +303,7 @@ We recommend adding the `updateMultisig` function, but so that only the old `mul ###### Fathom's response Implemented Auditors Recommendation. -#### 6. [NEW] There is no emergency shutdown mode in `Governor`[DONE] +#### 6. [NEW] There is no emergency shutdown mode in `Governor`[DONE -> ASK AUDITOR FOR HELP] ##### Description There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. ##### Recommendation diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index c23a1a7..812397c 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -16,7 +16,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A using SafeERC20Staking for IERC20; bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); - error LockIdLengthExceeded(uint256 _lockId, address _account); + error LockLengthExceeded(uint256 _lockId, address _account); constructor() { _disableInitializers(); @@ -222,7 +222,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function claimAllStreamRewardsForLock(uint256 lockId) public override pausable(1) { if(lockId > locks[msg.sender].length){ - revert LockIdLengthExceeded(lockId, msg.sender); + revert LockLengthExceeded(lockId, msg.sender); } require(lockId != 0, "lockId 0"); _updateStreamRPS(); @@ -296,7 +296,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function _verifyUnlock(uint256 lockId) internal view { require(lockId > 0, "zero lockid"); if(lockId > locks[msg.sender].length){ - revert LockIdLengthExceeded(lockId, msg.sender); + revert LockLengthExceeded(lockId, msg.sender); } LockedBalance storage lock = locks[msg.sender][lockId - 1]; require(lock.amountOfToken > 0, "no amount"); diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 22d6668..d9c0679 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -10,6 +10,8 @@ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; contract MultiSigWallet is IMultiSigWallet { using Address for address; using EnumerableSet for EnumerableSet.UintSet; + + uint256 public constant MINIMUM_LIFETIME = 86400;//oneDay struct Transaction { address to; bool executed; @@ -83,9 +85,9 @@ contract MultiSigWallet is IMultiSigWallet { address _to, uint256 _value, bytes memory _data, - uint256 _expireTimestamp + uint256 _lifetime ) { - require(_expireTimestamp >= block.timestamp || _expireTimestamp == 0, "already expired"); + require(_lifetime >= MINIMUM_LIFETIME || _lifetime == 0, "already expired"); if (!_to.isContract()) { require(_data.length == 0 && _value > 0, "calldata for EOA call or 0 value"); @@ -179,7 +181,6 @@ contract MultiSigWallet is IMultiSigWallet { ) public override onlyOwnerOrGov validateSubmitTxInputs(_to, _value, _data, _lifetime) { require(address(this).balance >= _value, "submitTransaction: not enough balance"); uint256 txIndex = transactions.length; - transactions.push( Transaction({ to: _to, @@ -235,10 +236,8 @@ contract MultiSigWallet is IMultiSigWallet { if(confirmedTransactionsByOwner[owners[i]].contains(_txIndex)){ confirmedTransactionsByOwner[owners[i]].remove(_txIndex); } - } (bool success, bytes memory data) = transaction.to.call{ value: transaction.value }(transaction.data); - emit ExecuteTransaction(msg.sender, _txIndex,success, data); } From 3ade6b7e93215bac46f083fc9bacca8776139b6f Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 1 Feb 2023 12:44:11 +0545 Subject: [PATCH 37/77] changed revert string --- contracts/dao/treasury/MultiSigWallet.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index d9c0679..7100ec7 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -87,7 +87,7 @@ contract MultiSigWallet is IMultiSigWallet { bytes memory _data, uint256 _lifetime ) { - require(_lifetime >= MINIMUM_LIFETIME || _lifetime == 0, "already expired"); + require(_lifetime >= MINIMUM_LIFETIME || _lifetime == 0, "lifetime minimum not met"); if (!_to.isContract()) { require(_data.length == 0 && _value > 0, "calldata for EOA call or 0 value"); From ed2d2a68378978310498d5fbdb34b00be7f6bb9c Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 1 Feb 2023 16:19:09 +0545 Subject: [PATCH 38/77] added safe transfer vault package --- audit-report/Fathom_DAO-review.md | 16 +++---- .../staking/vault/packages/VaultPackage.sol | 5 +-- scripts/tests/dao/demo/staking.demo.test.js | 43 +++++++++++++++++++ 3 files changed, 53 insertions(+), 11 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index d210b10..6d9db8e 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -303,7 +303,7 @@ We recommend adding the `updateMultisig` function, but so that only the old `mul ###### Fathom's response Implemented Auditors Recommendation. -#### 6. [NEW] There is no emergency shutdown mode in `Governor`[DONE -> ASK AUDITOR FOR HELP] +#### 6. [NEW] There is no emergency shutdown mode in `Governor`[DONE -> ASK AUDITOR FOR HELP, NOTDONE still] ##### Description There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. ##### Recommendation @@ -394,7 +394,7 @@ But it should be noted that `addToWhitelist` and `removeFromWhitelist` can be ca We recommend refactoring this code and adding internal functions `_addToWhitelist` and `_removeFromWhitelist` without access control to `grantMinterRole` and `revokeMinterRole`. -#### 3. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[DONE, Ask Anton] +#### 3. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[DONE, Ask Auditor] ##### Description In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. ##### Recommendation @@ -419,7 +419,7 @@ We recommend making two different functions for relaying `ERC20` tokens and nati -#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE] +#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor] ##### Description The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol) contract lacks the ability to suspend a contract in an emergency and migrate assets to a new compatible `VaultPackage` contract. @@ -487,7 +487,7 @@ We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppeli ###### Fathom's response Implemented Auditors Recommendation. -#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE] +#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE] ##### Description In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. @@ -565,7 +565,7 @@ bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); ###### Fathom's response Implemented Auditors Recommendation. -#### 5. [NEW] Transaction should be marked as `executed` if the call fails[NOTDONE -> CHECKAGAIN MAXJI!! Makes sense?] +#### 5. [NEW] Transaction should be marked as `executed` if the call fails[DONE Ask Auditor] ##### Description @@ -781,7 +781,7 @@ We recommend removing `Governance` from this modifier and give the permission to ###### Fathom's response Thats the way its designed -#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[DONE] +#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[DONE - Ask Auditor] ##### Description In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. Based on the logic of the contract, there may be the following cases: @@ -917,7 +917,7 @@ We recommend adding a check that `newProposalThreshold` is not zero. ###### Fathom's response Implemented Auditors Recommendation. -#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE, Ask Anton] +#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE, Ask Anton - Ask Auditor] ##### Description In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. ##### Recommendation @@ -1078,7 +1078,7 @@ Implemented Auditors Recommendation. ### INFO -#### 20. [NEW] There's no logging of reverted transactions in `MultiSigWallet`[DONE] +#### 20. [NEW] There's no logging of reverted transactions in `MultiSigWallet`[DONE, Check Again, Ask Auditor] ##### Description In the function [`executeConfirmation`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L144) there's no logging of failed transactions. ```solidity diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index 6a5baa7..7cb1451 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -89,7 +89,7 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { balanceToWithdraw = balanceInContract - deposited[_token]; } if(balanceToWithdraw > 0){ - IERC20(_token).transfer(_withdrawTo, balanceToWithdraw); + IERC20(_token).safeTransfer(_withdrawTo, balanceToWithdraw); } } } @@ -98,11 +98,10 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { require(!isSupportedToken[_token],"token is supported"); uint256 balanceInContract = IERC20(_token).balanceOf(address(this)); if(balanceInContract > 0){ - IERC20(_token).transfer(_withdrawTo, balanceInContract); + IERC20(_token).safeTransfer(_withdrawTo, balanceInContract); } } - /// @notice we believe newVaultPackage is safe function migrate(address newVaultPackage) external override onlyRole(DEFAULT_ADMIN_ROLE) { require(!migrated, "vault already migrated"); diff --git a/scripts/tests/dao/demo/staking.demo.test.js b/scripts/tests/dao/demo/staking.demo.test.js index 23ff8ab..7a5af13 100644 --- a/scripts/tests/dao/demo/staking.demo.test.js +++ b/scripts/tests/dao/demo/staking.demo.test.js @@ -74,6 +74,22 @@ const _encodeTransferFunction = (_account, t_to_stake) => { return toRet; } +const _encodeGrantRole = (role, account) => { + let toRet = web3.eth.abi.encodeFunctionCall({ + name: 'grantRole', + type: 'function', + inputs: [{ + type: 'bytes32', + name: 'role' + },{ + type: 'address', + name: 'account' + }] + }, [role, account]); + + return toRet; +} + const _encodeUpgradeFunction = (_proxy, _impl) => { let toRet = web3.eth.abi.encodeFunctionCall({ name: 'upgrade', @@ -594,6 +610,33 @@ describe("Staking Test and Upgrade Test", () => { await stakingService.createStream(streamId,RewardProposalAmountForAStream, {from: stream_rewarder_2}); }) + it("Should grant admin role to accounts[0] and withdraw extra supported tokens", async() =>{ + const _grantRoleMultisig = async (_role, _account) => { + const result = await multiSigWallet.submitTransaction( + vaultService.address, + EMPTY_BYTES, + _encodeGrantRole(_role, _account), + 0, + {"from": accounts[0]} + ); + txIndex4 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + + await multiSigWallet.confirmTransaction(txIndex4, {"from": accounts[0]}); + await multiSigWallet.confirmTransaction(txIndex4, {"from": accounts[1]}); + + await multiSigWallet.executeTransaction(txIndex4, {"from": accounts[1]}); + } + + await _grantRoleMultisig( + EMPTY_BYTES, + accounts[0] + ) + + await vaultService.withdrawExtraSupportedTokens(accounts[0], {"from": accounts[0]}); + }) + + + it('Should not be initalizable twice', async() => { const errorMessage = "Initializable: contract is already initialized"; shouldRevert( From 22c38c661eee67ce7c23e58d29c1f84b4cd8ae5e Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 1 Feb 2023 17:25:04 +0545 Subject: [PATCH 39/77] relayETH fix and test --- audit-report/Fathom_DAO-review.md | 2 +- contracts/dao/governance/Governor.sol | 4 +- .../dao/governance/MainTokenGovernor.sol | 6 +- .../dao/governance/TimelockController.sol | 2 +- .../dao/governance/proposal-flow.test.js | 199 +++++++++++++++--- 5 files changed, 180 insertions(+), 33 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 6d9db8e..fee1af8 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -272,7 +272,7 @@ We meant the `lifetime` parameter, which is passed as a function parameter. `transactions[_txIndex].expireTimestamp = block.timestamp + lifetime` -#### 5. [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[DONE -ASK AUDITOR] +#### 5. [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[DONE -ASK AUDITOR - VERIFIED] ##### Description In the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, Governance can take away the `TIMELOCK_ADMIN_ROLE` rights from the address `admin`. In the case of an attack on `Governance` and `Council` this would make it impossible to revoke the role from the captured contracts. ##### Recommendation diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index bd2bcff..fc438cc 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -28,7 +28,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { event MultiSigUpdated(address newMultiSig, address oldMultiSig); event MaxTargetUpdated(uint256 newMaxTargets, uint256 oldMaxTargets); event ProposalTimeDelayUpdated(uint256 newProposalTimeDelay, uint256 oldProposalTimeDelay); - event ExecuteTransaction(address indexed owner, bool success, bytes data); + event ExecuteTransaction(address indexed owner, bool indexed success, bytes data); bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); @@ -437,7 +437,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { ) internal virtual { for (uint256 i = 0; i < targets.length; ++i) { (bool success, bytes memory returndata) = targets[i].call{ value: values[i] }(calldatas[i]); - emit ExecuteTransaction(msg.sender,success, returndata); + emit ExecuteTransaction(msg.sender, success, returndata); } } diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index 64b1a72..a9ea900 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -107,7 +107,7 @@ contract MainTokenGovernor is Address.verifyCallResult(success, returndata, "Governor: relayERC20 reverted without message"); } - /** + /** * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor * is some contract other than the governor itself, like when using a timelock, this function can be invoked * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. @@ -115,10 +115,10 @@ contract MainTokenGovernor is */ function relayETH( address target, - uint256 value, bytes calldata data ) external payable virtual onlyGovernance { - (bool success, bytes memory returndata) = target.call{ value: value }(data); + require(!isSupportedToken[target],"relayEth: cant relay to supported token"); + (bool success, bytes memory returndata) = target.call{ value: address(this).balance }(data); Address.verifyCallResult(success, returndata, "Governor: relayETH reverted without message"); } diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index 6347502..65074f6 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -33,7 +33,7 @@ contract TimelockController is AccessControl, Initializable, ITimelockController */ event MinDelayChange(uint256 oldDuration, uint256 newDuration); - event ExecuteTransaction(address indexed owner, bool success, bytes data); + event ExecuteTransaction(address indexed owner, bool indexed success, bytes data); /** * @dev Modifier to make a function callable only by a certain role. In diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index c3dcd26..5f8a3e3 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -7,7 +7,7 @@ const { } = require('../../helpers/expectThrow'); const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; - +const TRUE_EVENT_RETURN_IN_HEX = "0x0000000000000000000000000000000000000000000000000000000000000001" // Proposal 1 const PROPOSAL_DESCRIPTION = "Proposal #1: Store 1 in the Box contract"; const NEW_STORE_VALUE = "5"; @@ -19,7 +19,7 @@ const AMOUNT_OUT_TREASURY = "1000"; // Events const PROPOSAL_CREATED_EVENT = "ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)" const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; - +const EXECUTE_TRANSACTION_EVENT = "ExecuteTransaction(address,bool,bytes)"; const _encodeConfirmation = async (_proposalId) => { return web3.eth.abi.encodeFunctionCall({ name: 'confirmProposal', @@ -35,7 +35,8 @@ const T_TO_STAKE = web3.utils.toWei('2000', 'ether'); const STAKED_MIN = web3.utils.toWei('1900', 'ether'); let streamReward1; let proposalIdForAddingSupportedToken; -let proposalIdForRelayFunction +let proposalIdForERC20elayFunction +let proposalIdForETHRelayFunction const STAKER_1 = accounts[5]; const STAKER_2 = accounts[6]; const NOT_STAKER = accounts[7]; @@ -89,7 +90,8 @@ describe('Proposal flow', () => { let lockingPeriod; let encoded_function_add_supporting_token; - let encoded_function_relay; + let encoded_function_ETH_relay; + let encoded_function_ERC20_relay; before(async () => { @@ -495,7 +497,6 @@ describe('Proposal flow', () => { } // Vote: await mainTokenGovernor.castVote(proposalId2, "1", {"from": STAKER_1}); - }); it("Should not allow an account to vote twice on the same proposal", async () => { @@ -718,8 +719,6 @@ describe('Proposal flow', () => { }); - - it('Create multiSig transaction to confirm proposal for adding supported tokens', async() => { encodedConfirmation1 = _encodeConfirmation(proposalIdForAddingSupportedToken); @@ -783,36 +782,35 @@ describe('Proposal flow', () => { description_hash, {"from": accounts[0]} ); + const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; + expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) }); /// ------------- Relay Token -------/// it('Propose to add relay Token to other address', async() => { await streamReward1.transfer(mainTokenGovernor.address,web3.utils.toWei("10000","ether"),{from: accounts[0]}); const eightHours = 28800 await blockchain.increaseTime(eightHours) - encoded_function_relay = web3.eth.abi.encodeFunctionCall({ - name: 'relay', + encoded_function_ERC20_relay = web3.eth.abi.encodeFunctionCall({ + name: 'relayERC20', type: 'function', inputs: [{ type: 'address', name: 'target' - },{ - type: 'uint256', - name: 'value' },{ type: 'bytes', name: 'data' }] - }, [streamReward1.address, EMPTY_BYTES, _encodeTransferFunction(accounts[0])]); + }, [streamReward1.address, _encodeTransferFunction(accounts[0])]); // create a proposal in MainToken governor result = await mainTokenGovernor.propose( [mainTokenGovernor.address], [0], - [encoded_function_relay], + [encoded_function_ERC20_relay], PROPOSAL_DESCRIPTION, {"from": STAKER_1} ); // retrieve the proposal id - proposalIdForRelayFunction = eventsHelper.getIndexedEventArgs(result, PROPOSAL_CREATED_EVENT)[0]; + proposalIdForERC20elayFunction = eventsHelper.getIndexedEventArgs(result, PROPOSAL_CREATED_EVENT)[0]; }); it('Wait two blocks and then check that the proposal status is: Active', async() => { @@ -827,7 +825,7 @@ describe('Proposal flow', () => { nextBlock++; } // Check that the proposal is open for voting - expect((await mainTokenGovernor.state(proposalIdForRelayFunction)).toString()).to.equal("1"); + expect((await mainTokenGovernor.state(proposalIdForERC20elayFunction)).toString()).to.equal("1"); }); it('Vote on the proposal', async() => { @@ -849,7 +847,7 @@ describe('Proposal flow', () => { nextBlock++; } // Vote: - await mainTokenGovernor.castVote(proposalIdForRelayFunction, "1", {"from": STAKER_1}); + await mainTokenGovernor.castVote(proposalIdForERC20elayFunction, "1", {"from": STAKER_1}); }); it('Wait 40 blocks and then check that the proposal status is: Succeeded', async() => { @@ -863,14 +861,11 @@ describe('Proposal flow', () => { nextBlock++; } - expect((await mainTokenGovernor.state(proposalIdForRelayFunction)).toString()).to.equal("4"); + expect((await mainTokenGovernor.state(proposalIdForERC20elayFunction)).toString()).to.equal("4"); }); - - - it('Create multiSig transaction to confirm proposal for relaying supported tokens', async() => { - encodedConfirmation1 = _encodeConfirmation(proposalIdForRelayFunction); + encodedConfirmation1 = _encodeConfirmation(proposalIdForERC20elayFunction); const result = await multiSigWallet.submitTransaction( mainTokenGovernor.address, @@ -906,7 +901,7 @@ describe('Proposal flow', () => { const result = await mainTokenGovernor.queue( [mainTokenGovernor.address], [0], - [encoded_function_relay], + [encoded_function_ERC20_relay], description_hash, {"from": accounts[0]} ); @@ -919,7 +914,7 @@ describe('Proposal flow', () => { await blockchain.mineBlock(timestamp + nextBlock); nextBlock++; } - expect((await mainTokenGovernor.state(proposalIdForRelayFunction)).toString()).to.equal("5"); + expect((await mainTokenGovernor.state(proposalIdForERC20elayFunction)).toString()).to.equal("5"); }); it('Execute the proposal', async() => { @@ -927,12 +922,164 @@ describe('Proposal flow', () => { const result = await mainTokenGovernor.execute( [mainTokenGovernor.address], [0], - [encoded_function_relay], + [encoded_function_ERC20_relay], description_hash, {"from": accounts[0], - } + } ); + + const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; + expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) }); + + //relay ETH + + /// ------------- Relay Token -------/// + it('Propose to add relay Token to other address', async() => { + const eightHours = 28800 + await blockchain.increaseTime(eightHours) + encoded_function_ETH_relay = web3.eth.abi.encodeFunctionCall({ + name: 'relayETH', + type: 'function', + inputs: [{ + type: 'address', + name: 'target' + },{ + type: 'bytes', + name: 'data' + }] + }, [accounts[0], _encodeTransferFunction(accounts[0])]); + // create a proposal in MainToken governor + result = await mainTokenGovernor.propose( + [mainTokenGovernor.address], + [0], + [encoded_function_ETH_relay], + PROPOSAL_DESCRIPTION, + {"from": STAKER_1} + ); + // retrieve the proposal id + proposalIdForETHRelayFunction = eventsHelper.getIndexedEventArgs(result, PROPOSAL_CREATED_EVENT)[0]; + }); + + it('Wait two blocks and then check that the proposal status is: Active', async() => { + + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 2) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + // Check that the proposal is open for voting + expect((await mainTokenGovernor.state(proposalIdForETHRelayFunction)).toString()).to.equal("1"); + }); + + it('Vote on the proposal', async() => { + + // enum VoteType { + // Against, + // For, + // Abstain + // } + // => 0 = Against, 1 = For, 2 = Abstain + + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 2) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + // Vote: + await mainTokenGovernor.castVote(proposalIdForETHRelayFunction, "1", {"from": STAKER_1}); + }); + + it('Wait 40 blocks and then check that the proposal status is: Succeeded', async() => { + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + const timestamp = block.timestamp; + + var nextBlock = 1; + while (nextBlock <= 40) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + + expect((await mainTokenGovernor.state(proposalIdForETHRelayFunction)).toString()).to.equal("4"); + }); + + it('Create multiSig transaction to confirm proposal for relaying supported tokens', async() => { + encodedConfirmation1 = _encodeConfirmation(proposalIdForETHRelayFunction); + + const result = await multiSigWallet.submitTransaction( + mainTokenGovernor.address, + EMPTY_BYTES, + encodedConfirmation1, + 0, + {"from": accounts[0]} + ); + txIndex1 = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + }) + + it('Should confirm transaction 1 from accounts[0], the first signer and accounts[1], the second signer', async() => { + await multiSigWallet.confirmTransaction(txIndex1, {"from": accounts[0]}); + await multiSigWallet.confirmTransaction(txIndex1, {"from": accounts[1]}); + }); + + + it('Execute the multiSig confirmation of proposal 1 and wait 40 blocks', async() => { + await multiSigWallet.executeTransaction(txIndex1, {"from": accounts[0]}); + }); + + it('Queue the proposal', async() => { + + // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the + // description parameter, which we need to hash. + // + // A proposal can only be executed if the proposalId is the same as the one stored + // in the governer contract that has passed a vote. + // In the Governor.sol contract, the proposalId is created using all information used + // in to create the proposal: + // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); + + const result = await mainTokenGovernor.queue( + [mainTokenGovernor.address], + [0], + [encoded_function_ETH_relay], + description_hash, + {"from": accounts[0]} + ); + const currentNumber = await web3.eth.getBlockNumber(); + const block = await web3.eth.getBlock(currentNumber); + + const timestamp = block.timestamp; + var nextBlock = 1; + while (nextBlock <= 40) { + await blockchain.mineBlock(timestamp + nextBlock); + nextBlock++; + } + expect((await mainTokenGovernor.state(proposalIdForETHRelayFunction)).toString()).to.equal("5"); + }); + + it('Execute the proposal', async() => { + + const result = await mainTokenGovernor.execute( + [mainTokenGovernor.address], + [0], + [encoded_function_ETH_relay], + description_hash, + {"from": accounts[0], + } + ); + + const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; + expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) + }); + }); }); From cb5c595c1e17c60881e7d606b3747f74ec005b36 Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 1 Feb 2023 17:43:46 +0545 Subject: [PATCH 40/77] relayNativeToken modified --- audit-report/Fathom_DAO-review.md | 4 ++-- contracts/dao/governance/MainTokenGovernor.sol | 11 ++++++----- contracts/dao/governance/TimelockController.sol | 2 -- contracts/dao/treasury/MultiSigWallet.sol | 2 -- scripts/tests/dao/governance/proposal-flow.test.js | 7 +++++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index fee1af8..5889bf8 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -256,7 +256,7 @@ modifier validRequirement(uint ownerCount, uint _required) { } ``` -#### [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet`[DONE -ASK AUDITOR] +#### [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet`[NOTDONE -ASK AUDITOR] ##### Description In the structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) there's no lifetime parameter `expired`, which is responsible for the period of time during which the transaction must be executed. Since transactions may be executed at random time and are not removed over time, frozen, previously not approved transactions can be executed after a certain time and cause an undesirable effect. ##### Recommendation @@ -303,7 +303,7 @@ We recommend adding the `updateMultisig` function, but so that only the old `mul ###### Fathom's response Implemented Auditors Recommendation. -#### 6. [NEW] There is no emergency shutdown mode in `Governor`[DONE -> ASK AUDITOR FOR HELP, NOTDONE still] +#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE -> ASK AUDITOR FOR HELP, NOTDONE still] ##### Description There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. ##### Recommendation diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index a9ea900..4f0acc5 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -101,7 +101,7 @@ contract MainTokenGovernor is function relayERC20( address target, bytes calldata data - ) external payable virtual onlyGovernance { + ) external virtual onlyGovernance { require(isSupportedToken[target], "relayERC20: token not supported"); (bool success, bytes memory returndata) = target.call(data); Address.verifyCallResult(success, returndata, "Governor: relayERC20 reverted without message"); @@ -113,13 +113,14 @@ contract MainTokenGovernor is * in a governance proposal to recover tokens or Ether that was sent to the governor contract by mistake. * Note that if the executor is simply the governor itself, use of `relay` is redundant. */ - function relayETH( + function relayNativeToken( address target, + uint256 value, bytes calldata data ) external payable virtual onlyGovernance { - require(!isSupportedToken[target],"relayEth: cant relay to supported token"); - (bool success, bytes memory returndata) = target.call{ value: address(this).balance }(data); - Address.verifyCallResult(success, returndata, "Governor: relayETH reverted without message"); + require(!isSupportedToken[target],"relayNativeToken: cant relay native token to supported token"); + (bool success, bytes memory returndata) = target.call{ value: value }(data); + Address.verifyCallResult(success, returndata, "Governor: relayNativeToken reverted without message"); } function _execute( diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index 65074f6..0a68c71 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -233,8 +233,6 @@ contract TimelockController is AccessControl, Initializable, ITimelockController _revokeRole(role, account); } - - function _execute( address target, uint256 value, diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 7100ec7..361cb61 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -94,7 +94,6 @@ contract MultiSigWallet is IMultiSigWallet { } require(address(this).balance >= _value, "not enough balance"); - _; } @@ -179,7 +178,6 @@ contract MultiSigWallet is IMultiSigWallet { bytes memory _data, uint256 _lifetime ) public override onlyOwnerOrGov validateSubmitTxInputs(_to, _value, _data, _lifetime) { - require(address(this).balance >= _value, "submitTransaction: not enough balance"); uint256 txIndex = transactions.length; transactions.push( Transaction({ diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 5f8a3e3..881770e 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -939,16 +939,19 @@ describe('Proposal flow', () => { const eightHours = 28800 await blockchain.increaseTime(eightHours) encoded_function_ETH_relay = web3.eth.abi.encodeFunctionCall({ - name: 'relayETH', + name: 'relayNativeToken', type: 'function', inputs: [{ type: 'address', name: 'target' + },{ + type: 'uint256', + name: 'value' },{ type: 'bytes', name: 'data' }] - }, [accounts[0], _encodeTransferFunction(accounts[0])]); + }, [accounts[0], EMPTY_BYTES, _encodeTransferFunction(accounts[0])]); // create a proposal in MainToken governor result = await mainTokenGovernor.propose( [mainTokenGovernor.address], From b9171f04bc69972b9372f69507f0c7491bac1890 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 2 Feb 2023 11:42:02 +0545 Subject: [PATCH 41/77] multisig owners and confirmed transactions --- audit-report/Fathom_DAO-review.md | 14 ++++----- contracts/dao/treasury/MultiSigWallet.sol | 36 ++++++++++++----------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 5889bf8..e6a5d17 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -143,7 +143,7 @@ Implemented Auditors Recommendation. with slight change: changeRequirement(numConfirmationsRequired + _owners.length); ``` -#### 1. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE -ASK Anton - ask auditor, does it require to revoke confirmation in submitTransaction] +#### 1. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE -ASK Anton - ask auditor, does it require to revoke confirmation in submitTransaction, TODAY] ##### Description In the function [`removeOwner`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L96) the owner is being removed without revocation of transaction signatures, where they've signed. This creates a situation where the signatures of non-existent owners may be used. For example, like in the following scenario: @@ -256,7 +256,7 @@ modifier validRequirement(uint ownerCount, uint _required) { } ``` -#### [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet`[NOTDONE -ASK AUDITOR] +#### [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet`[NOTDONE -ASK AUDITOR -Verified] ##### Description In the structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) there's no lifetime parameter `expired`, which is responsible for the period of time during which the transaction must be executed. Since transactions may be executed at random time and are not removed over time, frozen, previously not approved transactions can be executed after a certain time and cause an undesirable effect. ##### Recommendation @@ -303,7 +303,7 @@ We recommend adding the `updateMultisig` function, but so that only the old `mul ###### Fathom's response Implemented Auditors Recommendation. -#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE -> ASK AUDITOR FOR HELP, NOTDONE still] +#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE -> ASK AUDITOR FOR HELP, NOTDONE still TODAY] ##### Description There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. ##### Recommendation @@ -394,7 +394,7 @@ But it should be noted that `addToWhitelist` and `removeFromWhitelist` can be ca We recommend refactoring this code and adding internal functions `_addToWhitelist` and `_removeFromWhitelist` without access control to `grantMinterRole` and `revokeMinterRole`. -#### 3. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[DONE, Ask Auditor] +#### 3. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[DONE, Ask Auditor, Verified] ##### Description In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. ##### Recommendation @@ -438,7 +438,7 @@ We recommend forbidding to use functions after migration. We recommend using `deposited` variable instead `balanceOf` `VaultPackage` balance. -#### 4. [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE-> Do at last] +#### 4. [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE-> Do at last Ask Auditor TODAY] ##### Description In the `StakingHandlers` contract, calling the function [`updateVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L269) can cause all contract functions that work with balances and `VaultPackage` functions to be blocked. ##### Recommendation @@ -781,7 +781,7 @@ We recommend removing `Governance` from this modifier and give the permission to ###### Fathom's response Thats the way its designed -#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[DONE - Ask Auditor] +#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[DONE - Ask Auditor TODAY] ##### Description In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. Based on the logic of the contract, there may be the following cases: @@ -845,7 +845,7 @@ In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom- ##### Recommendation We recommend adding balance check while adding a transaction with a non-zero value `_value`. -#### [NEW] There is no time limit for executing proposal in `Governor`[Ask ANTON -DONE] +#### [NEW] There is no time limit for executing proposal in `Governor`[Ask ANTON -DONE Ask Auditor] ##### Description The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract has no parameters for the time limit on `proposal` execution. This can result in no longer relevant proposal being executed after a period of time. ##### Recommendation diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 361cb61..637b3aa 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -10,6 +10,7 @@ import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; contract MultiSigWallet is IMultiSigWallet { using Address for address; using EnumerableSet for EnumerableSet.UintSet; + using EnumerableSet for EnumerableSet.AddressSet; uint256 public constant MINIMUM_LIFETIME = 86400;//oneDay struct Transaction { @@ -25,7 +26,7 @@ contract MultiSigWallet is IMultiSigWallet { uint256 public constant MAX_OWNER_COUNT = 50; - address[] public owners; + EnumerableSet.AddressSet owners; address public governor; uint256 public numConfirmationsRequired; @@ -114,7 +115,7 @@ contract MultiSigWallet is IMultiSigWallet { require(!isOwner[owner], "owner not unique"); isOwner[owner] = true; - owners.push(owner); + owners.add(owner); emit OwnerAddition(owner); } @@ -127,16 +128,11 @@ contract MultiSigWallet is IMultiSigWallet { function removeOwner(address owner) public override onlyWallet ownerExists(owner) { isOwner[owner] = false; - for (uint256 i = 0; i < owners.length - 1; i++) - if (owners[i] == owner) { - owners[i] = owners[owners.length - 1]; - break; - } - owners.pop(); + owners.remove(owner); - if (numConfirmationsRequired > owners.length) changeRequirement(owners.length); + if (numConfirmationsRequired > owners.length()) changeRequirement(owners.length()); - uint256 nConfirmedTxnByOwner = confirmedTransactionsByOwner[owner].values().length; + uint256 nConfirmedTxnByOwner = confirmedTransactionsByOwner[owner].length(); for(uint i = nConfirmedTxnByOwner; i >1; i--){ uint256 _txIndex = confirmedTransactionsByOwner[owner].at(i-1); @@ -152,7 +148,7 @@ contract MultiSigWallet is IMultiSigWallet { public override onlyWallet - validRequirement(owners.length + _owners.length, numConfirmationsRequired + _owners.length) + validRequirement(owners.length() + _owners.length, numConfirmationsRequired + _owners.length) { for (uint256 i = 0; i < _owners.length; i++) { address owner = _owners[i]; @@ -160,14 +156,14 @@ contract MultiSigWallet is IMultiSigWallet { _requireNewOwner(owner); isOwner[owner] = true; - owners.push(owner); + owners.add(owner); emit OwnerAddition(owner); } changeRequirement(numConfirmationsRequired + _owners.length); } - function changeRequirement(uint256 _required) public override onlyWallet validRequirement(owners.length, _required) { + function changeRequirement(uint256 _required) public override onlyWallet validRequirement(owners.length(), _required) { numConfirmationsRequired = _required; emit RequirementChange(_required); } @@ -230,9 +226,10 @@ contract MultiSigWallet is IMultiSigWallet { transaction.executed = true; - for(uint i = 0; i < owners.length;i++){ - if(confirmedTransactionsByOwner[owners[i]].contains(_txIndex)){ - confirmedTransactionsByOwner[owners[i]].remove(_txIndex); + for(uint i = 0; i < owners.length();i++){ + if(confirmedTransactionsByOwner[owners.at(i)].contains(_txIndex)) + { + confirmedTransactionsByOwner[owners.at(i)].remove(_txIndex); } } (bool success, bytes memory data) = transaction.to.call{ value: transaction.value }(transaction.data); @@ -258,7 +255,12 @@ contract MultiSigWallet is IMultiSigWallet { } function getOwners() public view override returns (address[] memory) { - return owners; + uint256 lengthOfOwners = owners.length(); + address[] memory returnOwners = new address[](lengthOfOwners); + for(uint256 i; i < lengthOfOwners;i++){ + returnOwners[i] = owners.at(i); + } + return returnOwners; } function getTransactionCount() public view override returns (uint256) { From a6a1a0244809663a8f804969e4f2081683d37e50 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 2 Feb 2023 13:49:59 +0545 Subject: [PATCH 42/77] validate transferfrom and then only state and deposit updates --- contracts/dao/staking/packages/StakingHandler.sol | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 812397c..207e9dd 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -10,7 +10,6 @@ import "../interfaces/IStakingHandler.sol"; import "../vault/interfaces/IVault.sol"; import "../../../common/security/AdminPausable.sol"; import "../../../common/SafeERC20Staking.sol"; - // solhint-disable not-rely-on-time contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, AdminPausable { using SafeERC20Staking for IERC20; @@ -56,8 +55,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A uint256[] memory scheduleTimes, uint256[] memory scheduleRewards, uint256 tau - ) external override onlyRole(DEFAULT_ADMIN_ROLE) { + ) external override onlyRole(DEFAULT_ADMIN_ROLE){ require(!mainStreamInitialized,"init done"); + IERC20(mainToken).safeTransferFrom(msg.sender,address(this),scheduleRewards[0]); _validateStreamParameters(_owner, mainToken, scheduleRewards[MAIN_STREAM], scheduleRewards[MAIN_STREAM], scheduleTimes, scheduleRewards, tau); uint256 streamId = 0; Schedule memory schedule = Schedule(scheduleTimes, scheduleRewards); @@ -131,7 +131,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A emit StreamProposed(streamId, streamOwner, rewardToken, maxDepositAmount); } - function createStream(uint256 streamId, uint256 rewardTokenAmount) public override pausable(1) { + function createStream(uint256 streamId, uint256 rewardTokenAmount) public override pausable(1){ Stream storage stream = streams[streamId]; require(stream.status == StreamStatus.PROPOSED, "nt proposed"); require(stream.schedule.time[0] >= block.timestamp, "prop expire"); @@ -139,6 +139,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A require(rewardTokenAmount <= stream.maxDepositAmount, "rwrds high"); require(rewardTokenAmount >= stream.minDepositAmount, "rwrds low"); + IERC20(stream.rewardToken).safeTransferFrom(msg.sender,address(this), rewardTokenAmount); stream.status = StreamStatus.ACTIVE; @@ -284,10 +285,11 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A uint256 amount, uint256 lockPeriod, address account - ) internal { + ) internal{ require(locks[account].length <= maxLockPositions, "max locks"); require(amount > 0, "amount 0"); require(lockPeriod <= maxLockPeriod, "max time"); + IERC20(mainToken).safeTransferFrom(msg.sender,address(this),amount); _updateStreamRPS(); _lock(account, amount, lockPeriod); _transfer(amount,mainToken); @@ -303,8 +305,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A require(lock.owner == msg.sender, "bad owner"); } - function _transfer(uint256 _amount, address _token) internal { - IERC20(_token).safeTransferFrom(msg.sender,address(this),_amount); + function _transfer(uint256 _amount, address _token) internal{ IERC20(_token).safeApprove(vault,0); IERC20(_token).safeApprove(vault,_amount); IVault(vault).deposit(_token, _amount); From 7b7daacf28dc20c19f98067ba02dc4a8f71a8660 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 2 Feb 2023 17:08:39 +0545 Subject: [PATCH 43/77] custom error --- .../dao/staking/interfaces/IStakingHandler.sol | 1 + contracts/dao/staking/packages/StakingHandler.sol | 14 +++++++++++--- .../dao/staking/packages/StakingInternals.sol | 9 ++++----- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index a2629c6..dab4f55 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -7,6 +7,7 @@ import "../StakingStructs.sol"; import "./IStakingGetter.sol"; interface IStakingHandler { + function initializeStaking( address _admin, address _vault, diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 207e9dd..46a1897 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -15,8 +15,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A using SafeERC20Staking for IERC20; bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); - error LockLengthExceeded(uint256 _lockId, address _account); + error LockLengthExceeded(uint256 _lockId, address _account); + error NotPaused(); constructor() { _disableInitializers(); } @@ -257,6 +258,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A * @dev Disregard rewards for emergency unlock and withdraw */ function emergencyUnlockAndWithdraw() public override { + if (paused == 0){ + revert NotPaused(); + } require(paused != 0, "nt emergency"); uint256 numberOfLocks = locks[msg.sender].length; for (uint256 lockId = 1; lockId <= numberOfLocks; lockId++) { @@ -270,8 +274,12 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function updateVault(address _vault) public override onlyRole(DEFAULT_ADMIN_ROLE) { // enforce pausing this contract before updating the address. // This mitigates the risk of future invalid reward claims - require(paused != 0, "require pause"); - require(_vault != address(0), "0 addr"); + if (paused == 0){ + revert NotPaused(); + } + if(_vault == address(0)){ + revert ZeroAddress(); + } require(IVault(vault).migrated(), "!migrated"); vault = _vault; } diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index ccf8dcf..4b18e4e 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -15,7 +15,7 @@ import "../../../common/math/FullMath.sol"; contract StakingInternals is RewardsInternals { // solhint-disable not-rely-on-time - error ZeroAddress(address _address); + error ZeroAddress(); error ZeroTotalAmountOfStakedToken(); error ZeroAmountOfLockedToken(); function _initializeStaking( @@ -28,15 +28,14 @@ contract StakingInternals is RewardsInternals { uint256 _voteLockCoef ) internal { if(_mainToken == address(0x00)){ - revert ZeroAddress(_mainToken); + revert ZeroAddress(); } if(_voteToken == address(0x00)){ - revert ZeroAddress(_voteToken); + revert ZeroAddress(); } if(_vault == address(0x00)){ - revert ZeroAddress(_vault); + revert ZeroAddress(); } - require(_weight.maxWeightShares > _weight.minWeightShares, "bad share"); require(_weight.maxWeightPenalty > _weight.minWeightPenalty, "bad penalty"); require(_weight.penaltyWeightMultiplier * _weight.maxWeightPenalty <= 100000, "wrong weight"); From d937d92c48ee1dbe0f51356c072185c499ab7041 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 2 Feb 2023 17:14:59 +0545 Subject: [PATCH 44/77] emergency stop --- contracts/dao/governance/Governor.sol | 23 ++++++++--- .../dao/governance/MainTokenGovernor.sol | 38 +++++++++++++++++-- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index fc438cc..8b7987f 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -14,9 +14,8 @@ import "../../common/Context.sol"; import "../../common/Strings.sol"; import "./GovernorStructs.sol"; import "./interfaces/IGovernor.sol"; -import "../../common/security/Pausable.sol"; -abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { +abstract contract Governor is Context, ERC165, EIP712, IGovernor { using DoubleEndedQueue for DoubleEndedQueue.Bytes32Deque; using SafeCast for uint256; using Strings for *; @@ -29,6 +28,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { event MaxTargetUpdated(uint256 newMaxTargets, uint256 oldMaxTargets); event ProposalTimeDelayUpdated(uint256 newProposalTimeDelay, uint256 oldProposalTimeDelay); event ExecuteTransaction(address indexed owner, bool indexed success, bytes data); + event EmergencyStop(); bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); bytes32 public constant EXTENDED_BALLOT_TYPEHASH = keccak256("ExtendedBallot(uint256 proposalId,uint8 support,string reason,bytes params)"); @@ -36,6 +36,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { uint256 public proposalTimeDelay; string private _name; uint256[] private proposalIds; + uint256 public live; address private multiSig; uint256 public proposalLifetime; @@ -89,6 +90,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { maxTargets = maxTargets_; proposalTimeDelay = proposalTimeDelay_; proposalLifetime = proposalLifetime_; + live = 1; } receive() external payable virtual { @@ -100,7 +102,8 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { uint256[] memory values, bytes[] memory calldatas, bytes32 descriptionHash - ) public payable virtual override whenNotPaused returns (uint256) { + ) public payable virtual override returns (uint256) { + require(live == 1,"not live"); uint256 proposalId = hashProposal(targets, values, calldatas, descriptionHash); requireNotExpired(proposalId); requireConfirmed(proposalId); @@ -127,6 +130,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { } function castVote(uint256 proposalId, uint8 support) public virtual override returns (uint256) { + require(live == 1,"not live"); address voter = _msgSender(); return _castVote(proposalId, voter, support, ""); } @@ -136,6 +140,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { uint8 support, string memory reason ) public virtual override returns (uint256) { + require(live == 1,"not live"); address voter = _msgSender(); return _castVote(proposalId, voter, support, reason); } @@ -146,6 +151,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { string memory reason, bytes memory params ) public virtual override returns (uint256) { + require(live == 1,"not live"); address voter = _msgSender(); return _castVote(proposalId, voter, support, reason, params); } @@ -157,6 +163,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { bytes32 r, bytes32 s ) public virtual override returns (uint256) { + require(live == 1,"not live"); address voter = ECDSA.recover(_hashTypedDataV4(keccak256(abi.encode(BALLOT_TYPEHASH, proposalId, support))), v, r, s); return _castVote(proposalId, voter, support, ""); } @@ -170,6 +177,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { bytes32 r, bytes32 s ) public virtual override returns (uint256) { + require(live == 1,"not live"); address voter = ECDSA.recover( _hashTypedDataV4(keccak256(abi.encode(EXTENDED_BALLOT_TYPEHASH, proposalId, support, keccak256(bytes(reason)), keccak256(params)))), v, @@ -185,7 +193,8 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { uint256[] memory values, bytes[] memory calldatas, string memory description - ) public virtual override whenNotPaused returns (uint256) { + ) public virtual override returns (uint256) { + require(live == 1,"not live"); require(getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold"); require(block.timestamp > nextAcceptableProposalTimestamp[msg.sender], "Governor: Can only submit one proposal for a certain interval"); @@ -257,8 +266,10 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor, Pausable { proposalLifetime = newProposalLifetime; } - function emergencyStop() public onlyMultiSig { - _pause(); + function _emergencyStop() internal onlyMultiSig { + require(live == 1, "not-live"); + live = 0; + emit EmergencyStop(); } function getProposals(uint256 _numIndexes) diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index 4f0acc5..d1e5ad3 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -22,6 +22,7 @@ contract MainTokenGovernor is { using SafeERC20 for IERC20; mapping(address => bool) public isSupportedToken; + address[] public listOfSupportedTokens; constructor( IVotes _token, @@ -82,15 +83,44 @@ contract MainTokenGovernor is return super.state(proposalId); } + function emergencyStop() public onlyMultiSig{ + _emergencyStop(); + for(uint i = 0; i < listOfSupportedTokens.length;i++){ + address _token = listOfSupportedTokens[i]; + uint256 balanceInContract = IERC20(_token).balanceOf(address(this)); + if(balanceInContract > 0){ + IERC20(_token).safeTransfer(msg.sender, balanceInContract); + } + } + if (address(this).balance > 0){ + (bool sent,) = msg.sender.call{ value: (address(this).balance) }(""); + require(sent, "Failed to send ether"); + } + } + function addSupportingToken(address _token) public onlyGovernance { - require(!isSupportedToken[_token], "Token already supported"); + _addSupportedToken(_token); + } + function removeSupportingToken(address _token) public onlyGovernance { + _removeSupportingToken(_token); + } + + function _addSupportedToken(address _token) internal { + require(!isSupportedToken[_token], "Token already exists"); isSupportedToken[_token] = true; + listOfSupportedTokens.push(_token); } - function removeSupportingToken(address _token) public onlyGovernance { - require(isSupportedToken[_token], "Token is not supported"); - isSupportedToken[_token] = false; + function _removeSupportingToken(address _token) internal { + for (uint256 i = 0; i < listOfSupportedTokens.length; i++) { + if (listOfSupportedTokens[i] == _token) { + listOfSupportedTokens[i] = listOfSupportedTokens[listOfSupportedTokens.length - 1]; + break; + } + } + listOfSupportedTokens.pop(); } + /** * @dev Relays a transaction or function call to an arbitrary target. In cases where the governance executor From 8fb1ee281c18fc3fa192d168a1486423ffa7f6cd Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 2 Feb 2023 18:16:49 +0545 Subject: [PATCH 45/77] emergencyStop test --- contracts/dao/governance/Governor.sol | 4 +- .../dao/governance/proposal-flow.test.js | 67 ++++++++++++++++++- 2 files changed, 66 insertions(+), 5 deletions(-) diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 8b7987f..2555623 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -236,9 +236,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { function revokeConfirmation(uint256 _proposalId) public onlyMultiSig notExecuted(_proposalId) { requireConfirmed(_proposalId); - isConfirmed[_proposalId] = false; - emit RevokeConfirmation(msg.sender, _proposalId); } @@ -266,7 +264,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { proposalLifetime = newProposalLifetime; } - function _emergencyStop() internal onlyMultiSig { + function _emergencyStop() internal { require(live == 1, "not-live"); live = 0; emit EmergencyStop(); diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 881770e..53d8692 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -20,6 +20,7 @@ const AMOUNT_OUT_TREASURY = "1000"; const PROPOSAL_CREATED_EVENT = "ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)" const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; const EXECUTE_TRANSACTION_EVENT = "ExecuteTransaction(address,bool,bytes)"; + const _encodeConfirmation = async (_proposalId) => { return web3.eth.abi.encodeFunctionCall({ name: 'confirmProposal', @@ -31,6 +32,15 @@ const _encodeConfirmation = async (_proposalId) => { }, [_proposalId.toString()]); } +const _encodeEmergencyStop = () => { + return web3.eth.abi.encodeFunctionCall( + { + name: 'emergencyStop', + type: 'function', + inputs: [] + },[]); +} + const T_TO_STAKE = web3.utils.toWei('2000', 'ether'); const STAKED_MIN = web3.utils.toWei('1900', 'ether'); let streamReward1; @@ -1081,8 +1091,61 @@ describe('Proposal flow', () => { const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) - }); - + }); }); + + describe("Emergency Stop through multisig", async() => { + it('Emergency stop the governor', async() =>{ + + const _emergencyStopGovernor = async() => { + const result = await multiSigWallet.submitTransaction( + mainTokenGovernor.address, + EMPTY_BYTES, + _encodeEmergencyStop(), + 0, + {"from": accounts[0]} + ) + + const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(tx, {"from": accounts[0]}); + await multiSigWallet.confirmTransaction(tx, {"from": accounts[1]}); + await multiSigWallet.executeTransaction(tx, {"from": accounts[1]}); + } + + await _emergencyStopGovernor() + }) + + it('Should fail to propose on emergency stop', async() =>{ + let errorMessage = "not live"; + + await shouldRevert( + mainTokenGovernor.propose( + [box.address], + [0], + [encoded_function], + PROPOSAL_DESCRIPTION, + {"from": accounts[0]} + ), + errTypes.revert, + errorMessage + ); + }) + + it('Should fail to execute on emergency stop', async() =>{ + let errorMessage = "not live"; + await shouldRevert( + mainTokenGovernor.execute( + [mainTokenGovernor.address], + [0], + [encoded_function_ETH_relay], + description_hash, + {"from": accounts[0], + } + ), + errTypes.revert, + errorMessage + ); + }) + }) }); From 08be22b3097e0d9b481facf30e09224cbe05c629 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 2 Feb 2023 18:48:58 +0545 Subject: [PATCH 46/77] removing redundant isConfirmed --- contracts/dao/treasury/MultiSigWallet.sol | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 637b3aa..9dd720f 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -32,7 +32,6 @@ contract MultiSigWallet is IMultiSigWallet { uint256 public numConfirmationsRequired; mapping(address => bool) public isOwner; - mapping(uint256 => mapping(address => bool)) public isConfirmed; mapping(address => bytes32) internal whitelistedBytesCode; @@ -55,7 +54,7 @@ contract MultiSigWallet is IMultiSigWallet { } modifier notConfirmed(uint256 _txIndex) { - require(!isConfirmed[_txIndex][msg.sender], "MultiSig: tx already confirmed"); + require(!confirmedTransactionsByOwner[msg.sender].contains(_txIndex), "MultiSig: tx already confirmed"); _; } @@ -93,7 +92,6 @@ contract MultiSigWallet is IMultiSigWallet { if (!_to.isContract()) { require(_data.length == 0 && _value > 0, "calldata for EOA call or 0 value"); } - require(address(this).balance >= _value, "not enough balance"); _; } @@ -138,7 +136,6 @@ contract MultiSigWallet is IMultiSigWallet { uint256 _txIndex = confirmedTransactionsByOwner[owner].at(i-1); Transaction storage transaction = transactions[_txIndex]; transaction.numConfirmations -= 1; - isConfirmed[_txIndex][owner] = false; confirmedTransactionsByOwner[owner].remove(_txIndex); emit RevokeConfirmation(owner, _txIndex); } @@ -167,7 +164,6 @@ contract MultiSigWallet is IMultiSigWallet { numConfirmationsRequired = _required; emit RequirementChange(_required); } - function submitTransaction( address _to, uint256 _value, @@ -204,7 +200,6 @@ contract MultiSigWallet is IMultiSigWallet { _requireTargetCodeNotChanged(transaction.to); transaction.numConfirmations += 1; - isConfirmed[_txIndex][msg.sender] = true; confirmedTransactionsByOwner[msg.sender].add(_txIndex); emit ConfirmTransaction(msg.sender, _txIndex); @@ -246,10 +241,9 @@ contract MultiSigWallet is IMultiSigWallet { { Transaction storage transaction = transactions[_txIndex]; - require(isConfirmed[_txIndex][msg.sender], "tx not confirmed"); + require(confirmedTransactionsByOwner[msg.sender].contains(_txIndex), "tx not confirmed"); transaction.numConfirmations -= 1; - isConfirmed[_txIndex][msg.sender] = false; confirmedTransactionsByOwner[msg.sender].remove(_txIndex); emit RevokeConfirmation(msg.sender, _txIndex); } From 8cdb8eac2916c7b45731a2c672a7601e5b022cb6 Mon Sep 17 00:00:00 2001 From: ssubik Date: Fri, 3 Feb 2023 14:25:08 +0545 Subject: [PATCH 47/77] vault package fixes for migration --- audit-report/Fathom_DAO-review.md | 18 +++++++-------- .../dao/staking/packages/StakingHandler.sol | 23 ++++++++++++++----- .../dao/staking/packages/StakingInternals.sol | 5 ++-- .../staking/vault/packages/VaultPackage.sol | 14 +++++++++++ 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index e6a5d17..9bd1367 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -101,7 +101,7 @@ The reaudited commit identifier with implemented Oxorio's recommendations is [`d ### CRITICAL -#### [NEW] There's no `owners` array length validation in the constructor of `MultiSigWallet`[DONE] +#### [NEW] There's no `owners` array length validation in the constructor of `MultiSigWallet`[DONE - VERIFIED] ##### Description In the [MultiSigWallet\`s constructor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L76) there's no checking that the number of `owners` is less than or equal `MAX_OWNER_COUNT`. If the contract is created with `owners` with length more than `MAX_OWNER_COUNT` then that makes calls to `addOwner`, `changeRequirement` and `removeOwner` (which uses call `changeRequirement`) functions impossible because they use modifier `validRequirement` with this `require` statement: ```solidity @@ -180,7 +180,7 @@ We recommend adding logic that would allow you to cancel the execution of `propo ###### Fathom's response Implemented Auditors Recommendation. -#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE] +#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE - ASK AUDITOR] ##### Description A change of the `timelock` parameter in the [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L22) contract can lead to already executed `proposals` being able to be executed again. This is connected to the fact that the execution status of the transaction is saved only in the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, and the `GovernorTimelockControl` contract makes calls to the `TimelockController` functions to get the `proposals` status in the [`state`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L50) function. ##### Recommendation @@ -303,7 +303,7 @@ We recommend adding the `updateMultisig` function, but so that only the old `mul ###### Fathom's response Implemented Auditors Recommendation. -#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE -> ASK AUDITOR FOR HELP, NOTDONE still TODAY] +#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE -> ASK AUDITOR FOR HELP, TODAY ASK AUDITOR-Verified] ##### Description There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. ##### Recommendation @@ -346,7 +346,7 @@ We recommend adding a constant with the minimum allowable value of `_quorumNumer Implemented Auditors Recommendation. -#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE] +#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE - Ask Auditor] ##### Description In the [VMainToken](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) contract, for mint tokens, calling account, in addition to having `MINTER_ROLE` rights, must also be in the `isWhiteListed` list, since the mint function calls `_mint,` which contains [`_beforeTokenTransfer`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65) call. When `_beforeTokenTransfer` is called, it checks that the `msg.sender` address is in the `isWhiteListed` list. @@ -419,7 +419,7 @@ We recommend making two different functions for relaying `ERC20` tokens and nati -#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor] +#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor -> Do we need to have not migrated check in withdraw Extra supported tokens?] ##### Description The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol) contract lacks the ability to suspend a contract in an emergency and migrate assets to a new compatible `VaultPackage` contract. @@ -487,7 +487,7 @@ We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppeli ###### Fathom's response Implemented Auditors Recommendation. -#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE] +#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE , Ask Auditor] ##### Description In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. @@ -506,7 +506,7 @@ Recommendation has not been fully implemented. In the current version there is s We recommend adding a separate withdraw function, that would allow the `DEFAULT_ADMIN_ROLE` address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). -#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE] +#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE - Ask Auditor] ##### Description In the `StakingHandlers` contract the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function does not allocate tokens for rewards `MAIN_STREAM`, as it happens when [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) is called. This may result in the block of the `withdrawStream` function call from the `MAIN_STREAM` of tokens and rewards for some users, if the amount in `VaultPackage` is less than the amount stated in `scheduleRewards`. ##### Recommendation @@ -917,7 +917,7 @@ We recommend adding a check that `newProposalThreshold` is not zero. ###### Fathom's response Implemented Auditors Recommendation. -#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE, Ask Anton - Ask Auditor] +#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE, Ask Anton - Ask Auditor -TODAY!] ##### Description In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. ##### Recommendation @@ -1078,7 +1078,7 @@ Implemented Auditors Recommendation. ### INFO -#### 20. [NEW] There's no logging of reverted transactions in `MultiSigWallet`[DONE, Check Again, Ask Auditor] +#### 20. [NEW] There's no logging of reverted transactions in `MultiSigWallet`[DONE, Check Again, Ask Auditor -TODAY] ##### Description In the function [`executeConfirmation`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L144) there's no logging of failed transactions. ```solidity diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 46a1897..d6ade61 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -18,6 +18,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A error LockLengthExceeded(uint256 _lockId, address _account); error NotPaused(); + error VaultNotSupported(address _vault); + error VaultNotMigrated(address _vault); + error ZeroLockId(); constructor() { _disableInitializers(); } @@ -253,16 +256,15 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } } } - /** * @dev Disregard rewards for emergency unlock and withdraw */ function emergencyUnlockAndWithdraw() public override { - if (paused == 0){ + if(paused == 0){ revert NotPaused(); } - require(paused != 0, "nt emergency"); uint256 numberOfLocks = locks[msg.sender].length; + require(numberOfLocks > 0,"no locks"); for (uint256 lockId = 1; lockId <= numberOfLocks; lockId++) { LockedBalance storage lock = locks[msg.sender][lockId]; uint256 stakeValue = lock.amountOfToken; @@ -280,7 +282,12 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A if(_vault == address(0)){ revert ZeroAddress(); } - require(IVault(vault).migrated(), "!migrated"); + if(!IERC165Upgradeable(_vault).supportsInterface(type(IVault).interfaceId)){ + revert VaultNotSupported(_vault); + } + if(!IVault(vault).migrated()){ + revert VaultNotMigrated(vault); + } vault = _vault; } @@ -304,12 +311,16 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } function _verifyUnlock(uint256 lockId) internal view { - require(lockId > 0, "zero lockid"); + if(lockId == 0){ + revert ZeroLockId(); + } if(lockId > locks[msg.sender].length){ revert LockLengthExceeded(lockId, msg.sender); } LockedBalance storage lock = locks[msg.sender][lockId - 1]; - require(lock.amountOfToken > 0, "no amount"); + if(lock.amountOfToken == 0){ + revert ZeroAmountOfLockedToken(lockId); + } require(lock.owner == msg.sender, "bad owner"); } diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 4b18e4e..13564c0 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -17,7 +17,7 @@ contract StakingInternals is RewardsInternals { // solhint-disable not-rely-on-time error ZeroAddress(); error ZeroTotalAmountOfStakedToken(); - error ZeroAmountOfLockedToken(); + error ZeroAmountOfLockedToken(uint256 lockId); function _initializeStaking( address _mainToken, address _voteToken, @@ -98,9 +98,8 @@ contract StakingInternals is RewardsInternals { if(totalAmountOfStakedToken == 0){ revert ZeroTotalAmountOfStakedToken(); } - if(updateLock.amountOfToken == 0){ - revert ZeroAmountOfLockedToken(); + revert ZeroAmountOfLockedToken(lockId); } uint256 nVoteToken = updateLock.amountOfVoteToken; /// if you unstake, early or partial or complete, diff --git a/contracts/dao/staking/vault/packages/VaultPackage.sol b/contracts/dao/staking/vault/packages/VaultPackage.sol index 7cb1451..ed4c8d7 100644 --- a/contracts/dao/staking/vault/packages/VaultPackage.sol +++ b/contracts/dao/staking/vault/packages/VaultPackage.sol @@ -8,6 +8,7 @@ import "../interfaces/IVaultEvents.sol"; import "../../../tokens/ERC20/IERC20.sol"; import "../../../../common/security/AdminPausable.sol"; import "../../../../common/SafeERC20.sol"; +import "../../../../common/introspection/ERC165.sol"; // solhint-disable not-rely-on-time contract VaultPackage is IVault, IVaultEvents, AdminPausable { @@ -42,6 +43,8 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { require(isSupportedToken[_token], "Unsupported token"); require(_amount != 0, "amount zero"); require(deposited[_token] >= _amount, "payRewards: not enough deposit"); + require(!migrated,"vault already migrated"); + uint256 previousBalance = IERC20(_token).balanceOf(address(this)); IERC20(_token).safeTransfer(_user, _amount); uint256 newBalance = IERC20(_token).balanceOf(address(this)); @@ -55,6 +58,8 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { ) external override pausable(1) { require(hasRole(REWARDS_OPERATOR_ROLE, msg.sender), "deposit: No role"); require(isSupportedToken[_token], "Unsupported token"); + require(!migrated,"vault already migrated"); + uint256 previousBalance = IERC20(_token).balanceOf(address(this)); IERC20(_token).safeTransferFrom(msg.sender, address(this), _amount); uint256 newBalance = IERC20(_token).balanceOf(address(this)); @@ -67,14 +72,17 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { /// whitelisted here /// @param _token stream ERC20 token address function addSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) { + require(!migrated,"vault already migrated"); _addSupportedToken(_token); } /// @notice removed token as a supported rewards token by Treasury /// @param _token stream ERC20 token address function removeSupportedToken(address _token) external override onlyRole(DEFAULT_ADMIN_ROLE) { + require(!migrated,"vault already migrated"); require(isSupportedToken[_token], "Token does not exist"); require(deposited[_token] == 0, "Token is still in use"); + isSupportedToken[_token] = false; _removeToken(_token); emit TokenRemoved(_token, msg.sender, block.timestamp); @@ -116,6 +124,11 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { migrated = true; } + function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { + return interfaceId == type(IERC165).interfaceId || + interfaceId == type(IVault).interfaceId; + } + function _addSupportedToken(address _token) internal { require(!isSupportedToken[_token], "Token already exists"); isSupportedToken[_token] = true; @@ -133,4 +146,5 @@ contract VaultPackage is IVault, IVaultEvents, AdminPausable { listOfSupportedTokens.pop(); } + } From 625185143dbaf32325882d84a802d9e47540f2ea Mon Sep 17 00:00:00 2001 From: ssubik Date: Fri, 3 Feb 2023 18:07:03 +0545 Subject: [PATCH 48/77] checking event stream created --- contracts/dao/staking/interfaces/IStakingEvents.sol | 2 +- contracts/dao/staking/interfaces/IStakingGetter.sol | 8 +------- contracts/dao/staking/packages/StakingGetters.sol | 13 ++----------- contracts/dao/staking/packages/StakingHandler.sol | 4 ++-- scripts/migrations/prod/5_init_main_stream.js | 4 +++- scripts/migrations/test/6_init_main_stream.js | 5 +++-- 6 files changed, 12 insertions(+), 24 deletions(-) diff --git a/contracts/dao/staking/interfaces/IStakingEvents.sol b/contracts/dao/staking/interfaces/IStakingEvents.sol index 07d11f6..34ecdb8 100644 --- a/contracts/dao/staking/interfaces/IStakingEvents.sol +++ b/contracts/dao/staking/interfaces/IStakingEvents.sol @@ -9,7 +9,7 @@ interface IStakingEvents { event StreamProposed(uint256 indexed streamId, address indexed streamOwner, address indexed rewardToken, uint256 maxDepositAmount); event Released(uint256 indexed streamId, address indexed user, uint256 pendingAmount); event StreamProposalCancelled(uint256 indexed streamId, address indexed owner, address indexed token); - event StreamCreated(uint256 indexed streamId, address indexed owner, address indexed token, uint256 tau,uint256[] scheduleRewards, uint256[] scheduleTimes); + event StreamCreated(uint256 indexed streamId, address indexed owner, address indexed token, uint256 tau); event StreamRemoved(uint256 indexed streamId, address indexed owner, address indexed token); event Unstaked(address indexed account, uint256 amount, uint256 indexed lockId); event PartialUnstaked(address indexed account, uint256 amount, uint256 indexed lockId); diff --git a/contracts/dao/staking/interfaces/IStakingGetter.sol b/contracts/dao/staking/interfaces/IStakingGetter.sol index e0e6c2d..f0114a9 100644 --- a/contracts/dao/staking/interfaces/IStakingGetter.sol +++ b/contracts/dao/staking/interfaces/IStakingGetter.sol @@ -30,13 +30,7 @@ interface IStakingGetter { uint256 lockId ) external view returns (uint256); function readBySlot(uint256 slot) external view returns(bytes32); - function getStreamStatus(uint256 streamId) - external - view - returns ( - StreamStatus status - ); - //function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); + function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); // function getStreamsCount() external view returns (uint256); diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index f837729..4e8e5db 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -35,16 +35,7 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { function getAllLocks(address account) external override view returns (LockedBalance[] memory) { return locks[account]; } - function getStreamStatus(uint256 streamId) - external - view - override - returns ( - StreamStatus status - ) - { - return ( - streams[streamId].status - ); + function getStreamSchedule(uint256 streamId) external override view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards) { + return (streams[streamId].schedule.time, streams[streamId].schedule.reward); } } diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index d6ade61..889528e 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -84,7 +84,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A mainStreamInitialized =true; _transfer(scheduleRewards[0],mainToken); emit StreamProposed(streamId, _owner, mainToken, scheduleRewards[MAIN_STREAM]); - emit StreamCreated(streamId, _owner, mainToken, tau, scheduleRewards,scheduleTimes); + emit StreamCreated(streamId, _owner, mainToken, tau); } /** @@ -153,7 +153,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } require(stream.schedule.reward[0] == stream.rewardDepositAmount, "bad start"); - emit StreamCreated(streamId, stream.owner, stream.rewardToken,stream.tau,stream.schedule.time, stream.schedule.reward); + emit StreamCreated(streamId, stream.owner, stream.rewardToken,stream.tau); _transfer(rewardTokenAmount,stream.rewardToken); } diff --git a/scripts/migrations/prod/5_init_main_stream.js b/scripts/migrations/prod/5_init_main_stream.js index 61cca40..cf75123 100644 --- a/scripts/migrations/prod/5_init_main_stream.js +++ b/scripts/migrations/prod/5_init_main_stream.js @@ -9,6 +9,7 @@ const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; +const STREAM_CREATED_EVENT = "StreamCreated(uint256,address,address,uint256,uint256[],uint256[])" const T_TO_TRANSFER = web3.utils.toWei('20000', 'ether'); const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') @@ -107,5 +108,6 @@ module.exports = async function(deployer) { let txIndexInit = eventsHelper.getIndexedEventArgs(resultInit, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexInit, {gas: 8000000}); - await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); + let resultExeucteTransaction = await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); + console.log(eventsHelper.getAllIndexedEventArgs(resultExeucteTransaction,STREAM_CREATED_EVENT)) } diff --git a/scripts/migrations/test/6_init_main_stream.js b/scripts/migrations/test/6_init_main_stream.js index 17dbcd4..fec78a9 100644 --- a/scripts/migrations/test/6_init_main_stream.js +++ b/scripts/migrations/test/6_init_main_stream.js @@ -7,7 +7,7 @@ const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') const blockchain = require("../../tests/helpers/blockchain"); const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); -const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') +const STREAM_CREATED_EVENT = "StreamCreated(uint256,address,address,uint256)" const _getTimeStamp = async () => { const timestamp = await blockchain.getLatestBlockTimestamp(); return timestamp; @@ -101,5 +101,6 @@ module.exports = async function(deployer) { let txIndexInit = eventsHelper.getIndexedEventArgs(resultInit, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexInit, {gas: 8000000}); - await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); + let resultExeucteTransaction =await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); + console.log(eventsHelper.getAllIndexedEventArgs(resultExeucteTransaction,STREAM_CREATED_EVENT)) } From a23c34459f7013d68486107d7b870ef34cb2e664 Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 6 Feb 2023 11:26:52 +0545 Subject: [PATCH 49/77] reaudit --- contracts/dao/treasury/MultiSigWallet.sol | 13 ++--- .../treasury/interfaces/IMultiSigWallet.sol | 2 +- coralX-config.js | 2 +- coralX-scenarios.js | 2 +- .../deployment/5_deploy_governor.js | 2 +- .../prod/1_deploy_init_staking_proxy.js | 36 ------------- .../migrations/prod/2_add_vault_operator.js | 8 +-- scripts/migrations/prod/5_init_main_stream.js | 52 +++++++++---------- .../migrations/prod/6_setup_council_stakes.js | 5 +- scripts/migrations/prod/7_setup_multisig.js | 1 - 10 files changed, 39 insertions(+), 84 deletions(-) diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 9dd720f..fece51d 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -220,15 +220,12 @@ contract MultiSigWallet is IMultiSigWallet { require(transaction.numConfirmations >= numConfirmationsRequired, "cannot execute tx"); transaction.executed = true; + + (bool success, ) = transaction.to.call{ value: transaction.value }(transaction.data); - for(uint i = 0; i < owners.length();i++){ - if(confirmedTransactionsByOwner[owners.at(i)].contains(_txIndex)) - { - confirmedTransactionsByOwner[owners.at(i)].remove(_txIndex); - } - } - (bool success, bytes memory data) = transaction.to.call{ value: transaction.value }(transaction.data); - emit ExecuteTransaction(msg.sender, _txIndex,success, data); + require(success, "tx failed"); + + emit ExecuteTransaction(msg.sender, _txIndex); } function revokeConfirmation(uint256 _txIndex) diff --git a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol index 9ad8d8a..6aba109 100644 --- a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol +++ b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol @@ -9,7 +9,7 @@ interface IMultiSigWallet { event SubmitTransaction(uint256 indexed txIndex, address indexed owner, address indexed to, uint256 value, bytes data); event ConfirmTransaction(address indexed owner, uint256 indexed txIndex); event RevokeConfirmation(address indexed owner, uint256 indexed txIndex); - event ExecuteTransaction(address indexed owner, uint256 indexed txIndex, bool success,bytes data); + event ExecuteTransaction(address indexed owner, uint indexed txIndex); event OwnerRemoval(address indexed owner); event OwnerAddition(address indexed owner); event RequirementChange(uint256 required); diff --git a/coralX-config.js b/coralX-config.js index 2cee8e5..cfdb755 100644 --- a/coralX-config.js +++ b/coralX-config.js @@ -14,7 +14,7 @@ module.exports = { gasPrice: '0x3b9aca00', }, apothem: { - host: "https://rpc.apothem.network", + host: "https://arpc.apothem.network", private_key: fs.readFileSync("./privateKey").toString(), gasPrice: '0x3b9aca00', }, diff --git a/coralX-scenarios.js b/coralX-scenarios.js index 56dc312..e6b374c 100644 --- a/coralX-scenarios.js +++ b/coralX-scenarios.js @@ -27,7 +27,7 @@ module.exports = { ['execute', '--path', 'scripts/migrations/save-address/1_save_address_deployment.js'], ['execute', '--path', 'scripts/migrations/setup'], ['execute', '--path', 'scripts/migrations/save-address/2_save_address_setup.js'], - ['execute', '--path', 'scripts/migrations/test'], + ['execute', '--path', 'scripts/migrations/prod'], ['execute', '--path', 'scripts/migrations/save-address/3_save_address_prod.js'], ['execute', '--path', 'scripts/migrations/upgrades'], ], diff --git a/scripts/migrations/deployment/5_deploy_governor.js b/scripts/migrations/deployment/5_deploy_governor.js index fb044d4..5de539d 100644 --- a/scripts/migrations/deployment/5_deploy_governor.js +++ b/scripts/migrations/deployment/5_deploy_governor.js @@ -9,7 +9,7 @@ const MultiSigWallet_address = MultiSigWallet.address; const initialVotingDelay = 30; const votingPeriod = 450; const initialProposalThreshold = 1000; -const proposalTimeDelay = 2; +const proposalTimeDelay = 5; const proposalLifetime = 86400; diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index 90051f5..c1f1bc2 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -1,9 +1,7 @@ const RewardsCalculator = artifacts.require('./dao/staking/packages/RewardsCalculator.sol'); -const blockchain = require("../../tests/helpers/blockchain"); const VMainToken = artifacts.require('./dao/tokens/VMainToken.sol'); -const IStaking = artifacts.require('./dao/staking/interfaces/IStaking.sol'); const StakingPackage = artifacts.require('./dao/staking/packages/StakingPackage.sol'); const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); @@ -40,8 +38,6 @@ const _createVoteWeights = ( const vMainTokenCoefficient = 500; -const oneYear = 31556926; -const oneDay = 86400; const maxWeightShares = 1024; const minWeightShares = 768; @@ -50,8 +46,6 @@ const minWeightPenalty = 100; const weightMultiplier = 10; const maxNumberOfLocks = 10; -const tau = 60; - const lockingVoteWeight = 31556926; module.exports = async function(deployer) { @@ -69,36 +63,6 @@ module.exports = async function(deployer) { // const thirteenDecemberTimestampMidNight = 1670889600 const JanuaryFiveEIGHTPMUAE = 1672934400; - const startTime = JanuaryFiveEIGHTPMUAE; - - const scheduleTimes = [ - startTime, - startTime + 1 * oneDay, - startTime + 2 * oneDay, - startTime + 3 * oneDay, - startTime + 4 * oneDay, - startTime + 5 * oneDay, - startTime + 6 * oneDay, - startTime + 7 * oneDay, - startTime + 8 * oneDay, - startTime + 9 * oneDay, - startTime + 10 * oneDay - ]; - - const scheduleRewards = [ - web3.utils.toWei('150000000', 'ether'), - web3.utils.toWei('135000000', 'ether'), - web3.utils.toWei('120000000', 'ether'), - web3.utils.toWei('105000000', 'ether'), - web3.utils.toWei('90000000', 'ether'), - web3.utils.toWei('75000000', 'ether'), - web3.utils.toWei('60000000', 'ether'), - web3.utils.toWei('45000000', 'ether'), - web3.utils.toWei('30000000', 'ether'), - web3.utils.toWei('15000000', 'ether'), - web3.utils.toWei('0', 'ether') - ]; - const voteObject = _createVoteWeights( vMainTokenCoefficient, lockingVoteWeight diff --git a/scripts/migrations/prod/2_add_vault_operator.js b/scripts/migrations/prod/2_add_vault_operator.js index 112ff06..b2c45cf 100644 --- a/scripts/migrations/prod/2_add_vault_operator.js +++ b/scripts/migrations/prod/2_add_vault_operator.js @@ -1,19 +1,15 @@ const eventsHelper = require("../../tests/helpers/eventsHelper"); -const IVault = artifacts.require('./dao/staking/vault/interfaces/IVault.sol'); -const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); -const IERC20 = artifacts.require("./dao/tokens/ERC20/IERC20.sol"); const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const T_TO_TRANSFER = web3.utils.toWei('150000000', 'ether'); const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') -const _encodeTransferFunction = (_account, _amount) => { +const _encodeAddRewardsOpertor = (_account, _amount) => { let toRet = web3.eth.abi.encodeFunctionCall({ name: 'addRewardsOperator', type: 'function', @@ -32,7 +28,7 @@ module.exports = async function(deployer) { let result = await multiSigWallet.submitTransaction( VaultProxy.address, EMPTY_BYTES, - _encodeTransferFunction(StakingProxy.address), + _encodeAddRewardsOpertor(StakingProxy.address), 0, {gas: 8000000} ); diff --git a/scripts/migrations/prod/5_init_main_stream.js b/scripts/migrations/prod/5_init_main_stream.js index cf75123..949d815 100644 --- a/scripts/migrations/prod/5_init_main_stream.js +++ b/scripts/migrations/prod/5_init_main_stream.js @@ -1,26 +1,14 @@ const eventsHelper = require("../../tests/helpers/eventsHelper"); -const IVault = artifacts.require('./dao/staking/vault/interfaces/IVault.sol'); const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); -const IERC20 = artifacts.require("./dao/tokens/ERC20/IERC20.sol"); -const blockchain = require("../../tests/helpers/blockchain"); const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const STREAM_CREATED_EVENT = "StreamCreated(uint256,address,address,uint256,uint256[],uint256[])" -const T_TO_TRANSFER = web3.utils.toWei('20000', 'ether'); -const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') - -const _getTimeStamp = async () => { - const timestamp = await blockchain.getLatestBlockTimestamp(); - return timestamp; -} - const _encodeApproveFunction = (_account, _amount) => { let toRet = web3.eth.abi.encodeFunctionCall({ name: 'approve', @@ -65,22 +53,34 @@ const _encodeInitMainStreamFunction = (_owner, _scheduleTimes, _scheduleRewards, const tau = 2; module.exports = async function(deployer) { - const startTime = await _getTimeStamp() + 3 * 24 * 60 * 60; - const oneYear = 31556926; + const startTime = 1675526400 //EIGHT_PM_UAE_TIME_FEB_FOUR_Timestamp + const oneDay = 86400; const scheduleTimes = [ startTime, - startTime + oneYear, - startTime + 2 * oneYear, - startTime + 3 * oneYear, - startTime + 4 * oneYear, + startTime + 1 * oneDay, + startTime + 2 * oneDay, + startTime + 3 * oneDay, + startTime + 4 * oneDay, + startTime + 5 * oneDay, + startTime + 6 * oneDay, + startTime + 7 * oneDay, + startTime + 8 * oneDay, + startTime + 9 * oneDay, + startTime + 10 * oneDay ]; const scheduleRewards = [ - web3.utils.toWei('20000', 'ether'), - web3.utils.toWei('10000', 'ether'), - web3.utils.toWei('5000', 'ether'), - web3.utils.toWei('2500', 'ether'), - web3.utils.toWei("0", 'ether') + web3.utils.toWei('150000000', 'ether'), + web3.utils.toWei('135000000', 'ether'), + web3.utils.toWei('120000000', 'ether'), + web3.utils.toWei('105000000', 'ether'), + web3.utils.toWei('90000000', 'ether'), + web3.utils.toWei('75000000', 'ether'), + web3.utils.toWei('60000000', 'ether'), + web3.utils.toWei('45000000', 'ether'), + web3.utils.toWei('30000000', 'ether'), + web3.utils.toWei('15000000', 'ether'), + web3.utils.toWei('0', 'ether') ]; @@ -89,7 +89,7 @@ module.exports = async function(deployer) { let resultApprove = await multiSigWallet.submitTransaction( MainToken.address, EMPTY_BYTES, - _encodeApproveFunction(VaultProxy.address,scheduleRewards[0]), + _encodeApproveFunction(StakingProxy.address,scheduleRewards[0]), 0, {gas: 8000000} ) @@ -108,6 +108,6 @@ module.exports = async function(deployer) { let txIndexInit = eventsHelper.getIndexedEventArgs(resultInit, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexInit, {gas: 8000000}); - let resultExeucteTransaction = await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); - console.log(eventsHelper.getAllIndexedEventArgs(resultExeucteTransaction,STREAM_CREATED_EVENT)) + const resultOfInitMainStream = await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); + //const successStatusInitMainStream = eventsHelper.getIndexedEventArgs(resultOfInitMainStream, ExecuteTransactionSuccess); } diff --git a/scripts/migrations/prod/6_setup_council_stakes.js b/scripts/migrations/prod/6_setup_council_stakes.js index 34f96f6..3b89ddf 100644 --- a/scripts/migrations/prod/6_setup_council_stakes.js +++ b/scripts/migrations/prod/6_setup_council_stakes.js @@ -11,7 +11,7 @@ const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWa const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const LOCK_PERIOD = 365 * 24 * 60 * 60; +const LOCK_PERIOD = 4 * 24 * 60 * 60; const T_TO_TRANSFER = web3.utils.toWei('150000', 'ether'); const T_TO_STAKE = web3.utils.toWei('50000', 'ether'); @@ -19,7 +19,6 @@ const T_TO_STAKE = web3.utils.toWei('50000', 'ether'); const COUNCIL_1 = "0xc0Ee98ac1a44B56fbe2669A3B3C006DEB6fDd0f9"; const COUNCIL_2 = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') -const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') const _createLockParamObject = ( _amount, @@ -73,7 +72,7 @@ module.exports = async function(deployer) { let resultApprove = await multiSigWallet.submitTransaction( MainToken.address, EMPTY_BYTES, - _encodeApproveFunction(VaultProxy.address,T_TO_TRANSFER), + _encodeApproveFunction(StakingProxy.address,T_TO_TRANSFER), 0, {gas: 8000000} ) diff --git a/scripts/migrations/prod/7_setup_multisig.js b/scripts/migrations/prod/7_setup_multisig.js index d182e26..fc2373e 100644 --- a/scripts/migrations/prod/7_setup_multisig.js +++ b/scripts/migrations/prod/7_setup_multisig.js @@ -9,7 +9,6 @@ const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint const COUNCIL_1 = "0xc0Ee98ac1a44B56fbe2669A3B3C006DEB6fDd0f9"; const COUNCIL_2 = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; -const NEW_MULTISIG_REQUIREMENT = 3; const _encodeAddOwnersFunction = (_accounts) => { let toRet = web3.eth.abi.encodeFunctionCall({ From 465db3611d8b780703cfc8e318786ba1257bf967 Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 6 Feb 2023 12:29:47 +0545 Subject: [PATCH 50/77] fixing proposal lifetime --- audit-report/Fathom_DAO-review.md | 11 ++++++++--- contracts/dao/governance/Governor.sol | 3 ++- .../dao/staking/packages/StakingHandler.sol | 8 ++------ .../dao/staking/packages/StakingInternals.sol | 10 ++-------- contracts/dao/treasury/MultiSigWallet.sol | 13 +++++-------- .../treasury/interfaces/IMultiSigWallet.sol | 2 +- scripts/migrations/test/6_init_main_stream.js | 4 +--- scripts/tests/dao/staking/staking.test.js | 18 +++++++++++------- 8 files changed, 32 insertions(+), 37 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 9bd1367..4f5c647 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -438,7 +438,7 @@ We recommend forbidding to use functions after migration. We recommend using `deposited` variable instead `balanceOf` `VaultPackage` balance. -#### 4. [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE-> Do at last Ask Auditor TODAY] +#### 4. [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE-> Do at last Ask Auditor VERIFIED] ##### Description In the `StakingHandlers` contract, calling the function [`updateVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L269) can cause all contract functions that work with balances and `VaultPackage` functions to be blocked. ##### Recommendation @@ -565,7 +565,7 @@ bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); ###### Fathom's response Implemented Auditors Recommendation. -#### 5. [NEW] Transaction should be marked as `executed` if the call fails[DONE Ask Auditor] +#### 5. [NEW] Transaction should be marked as `executed` if the call fails[DONE Ask Auditor -NOTDONE, check again] ##### Description @@ -1535,4 +1535,9 @@ The following table contains the total number of issues that were found during a [FINDINGS] -Current audit revealed 75 issues of varying degrees of importance. For each founded issue the Contractor's team made recommendations on effective solving. \ No newline at end of file +Current audit revealed 75 issues of varying degrees of importance. For each founded issue the Contractor's team made recommendations on effective solving. + + +To Ask: + +Can you verify MultiSigWallet? \ No newline at end of file diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 2555623..5cb301c 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -28,6 +28,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { event MaxTargetUpdated(uint256 newMaxTargets, uint256 oldMaxTargets); event ProposalTimeDelayUpdated(uint256 newProposalTimeDelay, uint256 oldProposalTimeDelay); event ExecuteTransaction(address indexed owner, bool indexed success, bytes data); + event ProposalLifetimeUpdated(uint256 newProposalLifetime, uint256 oldProposalLifetime); event EmergencyStop(); bytes32 public constant BALLOT_TYPEHASH = keccak256("Ballot(uint256 proposalId,uint8 support)"); @@ -260,7 +261,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { function updateProposalLifetime(uint256 newProposalLifetime) public onlyMultiSig { require(newProposalLifetime>= MINIMUM_LIFETIME, "updateProposalLifetime: updateProposalLifetime less than minimum"); - emit ProposalTimeDelayUpdated(newProposalLifetime, newProposalLifetime); + emit ProposalLifetimeUpdated(newProposalLifetime, newProposalLifetime); proposalLifetime = newProposalLifetime; } diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 889528e..b4bf158 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -264,10 +264,8 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A revert NotPaused(); } uint256 numberOfLocks = locks[msg.sender].length; - require(numberOfLocks > 0,"no locks"); for (uint256 lockId = 1; lockId <= numberOfLocks; lockId++) { - LockedBalance storage lock = locks[msg.sender][lockId]; - uint256 stakeValue = lock.amountOfToken; + uint256 stakeValue = locks[msg.sender][lockId].amountOfToken; _unlock(stakeValue, stakeValue, lockId, msg.sender); } _withdraw(MAIN_STREAM); @@ -318,9 +316,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A revert LockLengthExceeded(lockId, msg.sender); } LockedBalance storage lock = locks[msg.sender][lockId - 1]; - if(lock.amountOfToken == 0){ - revert ZeroAmountOfLockedToken(lockId); - } + require(lock.amountOfToken != 0,"zeroLocked"); require(lock.owner == msg.sender, "bad owner"); } diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 13564c0..96ad8ea 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -16,8 +16,6 @@ import "../../../common/math/FullMath.sol"; contract StakingInternals is RewardsInternals { // solhint-disable not-rely-on-time error ZeroAddress(); - error ZeroTotalAmountOfStakedToken(); - error ZeroAmountOfLockedToken(uint256 lockId); function _initializeStaking( address _mainToken, address _voteToken, @@ -95,12 +93,8 @@ contract StakingInternals is RewardsInternals { ) internal { User storage userAccount = users[account]; LockedBalance storage updateLock = locks[account][lockId - 1]; - if(totalAmountOfStakedToken == 0){ - revert ZeroTotalAmountOfStakedToken(); - } - if(updateLock.amountOfToken == 0){ - revert ZeroAmountOfLockedToken(lockId); - } + require(totalAmountOfStakedToken !=0, "zeroTotal"); + require(updateLock.amountOfToken !=0,"zeroLocked"); uint256 nVoteToken = updateLock.amountOfVoteToken; /// if you unstake, early or partial or complete, /// the number of vote tokens for lock position is set to zero diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 9dd720f..fece51d 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -220,15 +220,12 @@ contract MultiSigWallet is IMultiSigWallet { require(transaction.numConfirmations >= numConfirmationsRequired, "cannot execute tx"); transaction.executed = true; + + (bool success, ) = transaction.to.call{ value: transaction.value }(transaction.data); - for(uint i = 0; i < owners.length();i++){ - if(confirmedTransactionsByOwner[owners.at(i)].contains(_txIndex)) - { - confirmedTransactionsByOwner[owners.at(i)].remove(_txIndex); - } - } - (bool success, bytes memory data) = transaction.to.call{ value: transaction.value }(transaction.data); - emit ExecuteTransaction(msg.sender, _txIndex,success, data); + require(success, "tx failed"); + + emit ExecuteTransaction(msg.sender, _txIndex); } function revokeConfirmation(uint256 _txIndex) diff --git a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol index 9ad8d8a..0fde3f9 100644 --- a/contracts/dao/treasury/interfaces/IMultiSigWallet.sol +++ b/contracts/dao/treasury/interfaces/IMultiSigWallet.sol @@ -9,7 +9,7 @@ interface IMultiSigWallet { event SubmitTransaction(uint256 indexed txIndex, address indexed owner, address indexed to, uint256 value, bytes data); event ConfirmTransaction(address indexed owner, uint256 indexed txIndex); event RevokeConfirmation(address indexed owner, uint256 indexed txIndex); - event ExecuteTransaction(address indexed owner, uint256 indexed txIndex, bool success,bytes data); + event ExecuteTransaction(address indexed owner, uint256 indexed txIndex); event OwnerRemoval(address indexed owner); event OwnerAddition(address indexed owner); event RequirementChange(uint256 required); diff --git a/scripts/migrations/test/6_init_main_stream.js b/scripts/migrations/test/6_init_main_stream.js index fec78a9..ec95a52 100644 --- a/scripts/migrations/test/6_init_main_stream.js +++ b/scripts/migrations/test/6_init_main_stream.js @@ -7,7 +7,6 @@ const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') const blockchain = require("../../tests/helpers/blockchain"); const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); -const STREAM_CREATED_EVENT = "StreamCreated(uint256,address,address,uint256)" const _getTimeStamp = async () => { const timestamp = await blockchain.getLatestBlockTimestamp(); return timestamp; @@ -101,6 +100,5 @@ module.exports = async function(deployer) { let txIndexInit = eventsHelper.getIndexedEventArgs(resultInit, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexInit, {gas: 8000000}); - let resultExeucteTransaction =await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); - console.log(eventsHelper.getAllIndexedEventArgs(resultExeucteTransaction,STREAM_CREATED_EVENT)) + await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); } diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index a41d600..2cc584d 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -994,6 +994,8 @@ describe("Staking Test", () => { }) + + it("Should unlock all lock positions: ", async() =>{ const lockingPeriod = 370* 24 * 60 * 60 @@ -1178,6 +1180,13 @@ describe("Staking Test", () => { assert(totalPenaltyBalance.toString(),"0") }) + it('Should should make lock position with 0 lock period', async() => { + const unlockTime = 0; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + it('Paused contract should not make lock position', async() => { const toPauseFlag = 1 @@ -1212,7 +1221,7 @@ describe("Staking Test", () => { errorMessage ); }) - + it('Unpaused contract should make lock position', async() => { const toUnPauseFlag = 0 const _unpauseStakingContract = async( @@ -1243,12 +1252,7 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + 100); }) - it('Should should make lock position with 0 lock period', async() => { - const unlockTime = 0; - await blockchain.mineBlock(await _getTimeStamp() + 100); - let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}); - await blockchain.mineBlock(await _getTimeStamp() + 100); - }) + it('Should not be initalizable twice - Vault', async() => { From 7f54ae7d105b2aadf8975a6e811a46b3b4247f5f Mon Sep 17 00:00:00 2001 From: ssubik Date: Tue, 7 Feb 2023 13:09:56 +0545 Subject: [PATCH 51/77] setting up demo environment --- audit-report/Fathom_DAO-review.md | 8 ++++---- coralX-scenarios.js | 2 +- scripts/migrations/prod/1_deploy_init_staking_proxy.js | 2 -- scripts/migrations/prod/5_init_main_stream.js | 5 +++-- scripts/migrations/prod/6_setup_council_stakes.js | 4 ++-- 5 files changed, 10 insertions(+), 11 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 4f5c647..edc8ab6 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -419,7 +419,7 @@ We recommend making two different functions for relaying `ERC20` tokens and nati -#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor -> Do we need to have not migrated check in withdraw Extra supported tokens?] +#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor -> Do we need to have not migrated check in withdraw Extra supported tokens Verified?] ##### Description The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol) contract lacks the ability to suspend a contract in an emergency and migrate assets to a new compatible `VaultPackage` contract. @@ -487,7 +487,7 @@ We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppeli ###### Fathom's response Implemented Auditors Recommendation. -#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE , Ask Auditor] +#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE , Ask Auditor -Verified] ##### Description In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. @@ -506,7 +506,7 @@ Recommendation has not been fully implemented. In the current version there is s We recommend adding a separate withdraw function, that would allow the `DEFAULT_ADMIN_ROLE` address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). -#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE - Ask Auditor] +#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE - Ask Auditor -VEFIRIED] ##### Description In the `StakingHandlers` contract the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function does not allocate tokens for rewards `MAIN_STREAM`, as it happens when [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) is called. This may result in the block of the `withdrawStream` function call from the `MAIN_STREAM` of tokens and rewards for some users, if the amount in `VaultPackage` is less than the amount stated in `scheduleRewards`. ##### Recommendation @@ -794,7 +794,7 @@ We recommend adding parameter checking when adding a transaction according to po ##### Update ###### Fathom's response Implemented Auditors Recommendation. -###### Oxorio's response +###### Oxorio's responsea The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/treasury/MultiSigWallet.sol#L94) is not implemented correctly. diff --git a/coralX-scenarios.js b/coralX-scenarios.js index e6b374c..56dc312 100644 --- a/coralX-scenarios.js +++ b/coralX-scenarios.js @@ -27,7 +27,7 @@ module.exports = { ['execute', '--path', 'scripts/migrations/save-address/1_save_address_deployment.js'], ['execute', '--path', 'scripts/migrations/setup'], ['execute', '--path', 'scripts/migrations/save-address/2_save_address_setup.js'], - ['execute', '--path', 'scripts/migrations/prod'], + ['execute', '--path', 'scripts/migrations/test'], ['execute', '--path', 'scripts/migrations/save-address/3_save_address_prod.js'], ['execute', '--path', 'scripts/migrations/upgrades'], ], diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index c1f1bc2..11e1995 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -60,8 +60,6 @@ module.exports = async function(deployer) { weightMultiplier ); - // const thirteenDecemberTimestampMidNight = 1670889600 - const JanuaryFiveEIGHTPMUAE = 1672934400; const voteObject = _createVoteWeights( vMainTokenCoefficient, diff --git a/scripts/migrations/prod/5_init_main_stream.js b/scripts/migrations/prod/5_init_main_stream.js index 949d815..964d38f 100644 --- a/scripts/migrations/prod/5_init_main_stream.js +++ b/scripts/migrations/prod/5_init_main_stream.js @@ -50,10 +50,11 @@ const _encodeInitMainStreamFunction = (_owner, _scheduleTimes, _scheduleRewards, return toInitializeMainStream } -const tau = 2; +const tau = 60; module.exports = async function(deployer) { - const startTime = 1675526400 //EIGHT_PM_UAE_TIME_FEB_FOUR_Timestamp + // const startTime = 1675526400 //EIGHT_PM_UAE_TIME_FEB_FOUR_Timestamp + const startTime = 1675756800 //TWELVE_PM_UAE_TIME_FEB_SEVEN_Timestamp const oneDay = 86400; const scheduleTimes = [ startTime, diff --git a/scripts/migrations/prod/6_setup_council_stakes.js b/scripts/migrations/prod/6_setup_council_stakes.js index 3b89ddf..e4d1e22 100644 --- a/scripts/migrations/prod/6_setup_council_stakes.js +++ b/scripts/migrations/prod/6_setup_council_stakes.js @@ -13,8 +13,8 @@ const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint const LOCK_PERIOD = 4 * 24 * 60 * 60; -const T_TO_TRANSFER = web3.utils.toWei('150000', 'ether'); -const T_TO_STAKE = web3.utils.toWei('50000', 'ether'); +const T_TO_TRANSFER = web3.utils.toWei('150000000', 'ether'); +const T_TO_STAKE = web3.utils.toWei('50000000', 'ether'); const COUNCIL_1 = "0xc0Ee98ac1a44B56fbe2669A3B3C006DEB6fDd0f9"; const COUNCIL_2 = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; From 13792ea2e89a85c6a014cfd86be4f77eb2b5476b Mon Sep 17 00:00:00 2001 From: ssubik Date: Tue, 7 Feb 2023 18:22:38 +0545 Subject: [PATCH 52/77] fixing one overflow with nvotetoken --- contracts/dao/staking/StakingStructs.sol | 2 +- contracts/dao/staking/helpers/IStakingGetterHelper.sol | 4 ++-- contracts/dao/staking/helpers/StakingGettersHelper.sol | 6 +++--- contracts/dao/staking/packages/StakingInternals.sol | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/contracts/dao/staking/StakingStructs.sol b/contracts/dao/staking/StakingStructs.sol index 2e407b4..14393c4 100644 --- a/contracts/dao/staking/StakingStructs.sol +++ b/contracts/dao/staking/StakingStructs.sol @@ -46,10 +46,10 @@ struct VoteCoefficient { struct LockedBalance { uint128 amountOfToken; - uint128 amountOfVoteToken; uint128 positionStreamShares; uint64 end; address owner; + uint256 amountOfVoteToken; } struct Stream { address owner; // stream owned by the ERC-20 reward token owner diff --git a/contracts/dao/staking/helpers/IStakingGetterHelper.sol b/contracts/dao/staking/helpers/IStakingGetterHelper.sol index 99506fc..baf706f 100644 --- a/contracts/dao/staking/helpers/IStakingGetterHelper.sol +++ b/contracts/dao/staking/helpers/IStakingGetterHelper.sol @@ -15,11 +15,11 @@ interface IStakingGetterHelper { external view returns ( - uint128, uint128, uint128, uint64, - address + address, + uint256 ); function getUserTotalDeposit(address account) external view returns (uint256); diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index 7de25ff..06acea2 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -36,18 +36,18 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { view override returns ( - uint128, uint128, uint128, uint64, - address + address, + uint256 ) { LockedBalance[] memory locks = _getAllLocks(account); LockedBalance memory lock = locks[lockId - 1]; require(lockId <= locks.length, "out of index"); require(lockId > 0, "lockId cant be 0"); - return (lock.amountOfToken, lock.amountOfVoteToken, lock.positionStreamShares, lock.end, lock.owner); + return (lock.amountOfToken, lock.positionStreamShares, lock.end, lock.owner,lock.amountOfVoteToken); } function getUserTotalDeposit(address account) public view override returns (uint256) { diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 96ad8ea..45dffd0 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -61,7 +61,7 @@ contract StakingInternals is RewardsInternals { } LockedBalance memory _newLock = LockedBalance({ amountOfToken: BoringMath.to128(amount), - amountOfVoteToken: BoringMath.to128(nVoteToken), + amountOfVoteToken: nVoteToken, positionStreamShares: 0, end: BoringMath.to64(lockPeriod + block.timestamp), owner: account From 3f7bea82e706b70747ed32e84993ac6c0ec8f01e Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 8 Feb 2023 12:38:40 +0545 Subject: [PATCH 53/77] removed full math and sload --- contracts/dao/staking/StakingStorage.sol | 6 +- .../staking/helpers/StakingGettersHelper.sol | 55 +++++++++---------- .../dao/staking/interfaces/IStakingGetter.sol | 2 +- .../staking/interfaces/IStakingStorage.sol | 2 + .../dao/staking/packages/RewardsInternals.sol | 7 ++- .../dao/staking/packages/StakingGetters.sol | 27 +++++++-- coralX-config.js | 4 +- 7 files changed, 59 insertions(+), 44 deletions(-) diff --git a/contracts/dao/staking/StakingStorage.sol b/contracts/dao/staking/StakingStorage.sol index 56020ee..fbffcf4 100644 --- a/contracts/dao/staking/StakingStorage.sol +++ b/contracts/dao/staking/StakingStorage.sol @@ -9,8 +9,8 @@ import "./library/StakingLibrary.sol"; contract StakingStorage { uint256 internal constant MAIN_STREAM = 0; - //Set according to Tokenomics: 1e50 -> 1e50/1e18. So Max Supply is 1 * 1e32; - uint256 internal constant RPS_MULTIPLIER = 1e50; + //Set according to Tokenomics: Max Supply: 1e9 * 1e18, weight = 1e3, tolerance for changes = 6, so 1e36 + uint256 internal constant RPS_MULTIPLIER = 1e36; uint128 internal constant POINT_MULTIPLIER = 1e18; uint64 internal constant ONE_MONTH = 2629746; uint64 internal constant ONE_YEAR = 31536000; @@ -45,7 +45,7 @@ contract StakingStorage { bool public mainStreamInitialized; ///Weighting coefficient for shares and penalties - Weight internal weight; + Weight public weight; mapping(address => User) public users; diff --git a/contracts/dao/staking/helpers/StakingGettersHelper.sol b/contracts/dao/staking/helpers/StakingGettersHelper.sol index 06acea2..389e079 100644 --- a/contracts/dao/staking/helpers/StakingGettersHelper.sol +++ b/contracts/dao/staking/helpers/StakingGettersHelper.sol @@ -10,7 +10,7 @@ import "../../../common/access/AccessControl.sol"; contract StakingGettersHelper is IStakingGetterHelper, AccessControl { address private stakingContract; - uint256 public constant WEIGHT_SLOT = 14; // the storage slot in staking contract where WEIGHT resides + //uint256 public constant WEIGHT_SLOT = 14; // the storage slot in staking contract where WEIGHT resides constructor(address _stakingContract, address admin) { stakingContract = _stakingContract; _grantRole(DEFAULT_ADMIN_ROLE, admin); @@ -120,34 +120,29 @@ contract StakingGettersHelper is IStakingGetterHelper, AccessControl { maxLockPeriod); } function _getWeight() internal view returns (Weight memory) { - bytes32 weight = IStakingHelper(stakingContract).readBySlot(WEIGHT_SLOT); - uint32 penaltyWeightMultiplier; - uint32 minWeightPenalty; - uint32 maxWeightPenalty; - uint32 minWeightShares; - uint32 maxWeightShares; - assembly { - let value := weight - maxWeightShares := and(0xffffffff, value) - //shift right by 32 then, do and by 32 bits to get the value - let minWeightShares_shifted:= shr(32,value) - minWeightShares := and(0xffffffff, minWeightShares_shifted) - //shift right by 64 then, do and by 32 bits to get the value - let maxWeightPenalty_shifted := shr(64,value) - maxWeightPenalty := and(0xffffffff, maxWeightPenalty_shifted) - //shift right by 96 then, do and by 32 bits to get the value - let minWeightPenalty_shifted := shr(96,value) - minWeightPenalty := and(0xffffffff, minWeightPenalty_shifted) - //shift right by 128 then, do and by 32 bits to get the value - let penaltyWeightMultiplier_shifted := shr(128,value) - penaltyWeightMultiplier := and(0xffffffff, penaltyWeightMultiplier_shifted) - } - return Weight( - maxWeightShares, - minWeightShares, - maxWeightPenalty, - minWeightPenalty, - penaltyWeightMultiplier - ); + //bytes32 weight = IStakingHelper(stakingContract).readBySlot(WEIGHT_SLOT); + // uint32 penaltyWeightMultiplier; + // uint32 minWeightPenalty; + // uint32 maxWeightPenalty; + // uint32 minWeightShares; + // uint32 maxWeightShares; + // assembly { + // let value := weight + // maxWeightShares := and(0xffffffff, value) + // //shift right by 32 then, do and by 32 bits to get the value + // let minWeightShares_shifted:= shr(32,value) + // minWeightShares := and(0xffffffff, minWeightShares_shifted) + // //shift right by 64 then, do and by 32 bits to get the value + // let maxWeightPenalty_shifted := shr(64,value) + // maxWeightPenalty := and(0xffffffff, maxWeightPenalty_shifted) + // //shift right by 96 then, do and by 32 bits to get the value + // let minWeightPenalty_shifted := shr(96,value) + // minWeightPenalty := and(0xffffffff, minWeightPenalty_shifted) + // //shift right by 128 then, do and by 32 bits to get the value + // let penaltyWeightMultiplier_shifted := shr(128,value) + // penaltyWeightMultiplier := and(0xffffffff, penaltyWeightMultiplier_shifted) + // } + + return IStakingStorage(stakingContract).weight(); } } diff --git a/contracts/dao/staking/interfaces/IStakingGetter.sol b/contracts/dao/staking/interfaces/IStakingGetter.sol index f0114a9..62a4507 100644 --- a/contracts/dao/staking/interfaces/IStakingGetter.sol +++ b/contracts/dao/staking/interfaces/IStakingGetter.sol @@ -29,7 +29,7 @@ interface IStakingGetter { address account, uint256 lockId ) external view returns (uint256); - function readBySlot(uint256 slot) external view returns(bytes32); + //function readBySlot(uint256 slot) external view returns(bytes32); function getStreamSchedule(uint256 streamId) external view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards); // function getStreamsCount() external view returns (uint256); diff --git a/contracts/dao/staking/interfaces/IStakingStorage.sol b/contracts/dao/staking/interfaces/IStakingStorage.sol index f24bd09..5553736 100644 --- a/contracts/dao/staking/interfaces/IStakingStorage.sol +++ b/contracts/dao/staking/interfaces/IStakingStorage.sol @@ -17,4 +17,6 @@ interface IStakingStorage { function totalPenaltyBalance() external view returns (uint256); function streamTotalUserPendings(uint256 streamId) external view returns (uint256); + function weight() external view returns (Weight memory); + } diff --git a/contracts/dao/staking/packages/RewardsInternals.sol b/contracts/dao/staking/packages/RewardsInternals.sol index 9dd4007..22decc9 100644 --- a/contracts/dao/staking/packages/RewardsInternals.sol +++ b/contracts/dao/staking/packages/RewardsInternals.sol @@ -6,14 +6,14 @@ pragma solidity 0.8.16; import "../StakingStorage.sol"; import "../interfaces/IStakingEvents.sol"; import "../interfaces/IRewardsHandler.sol"; -import "../../../common/math/FullMath.sol"; +//import "../../../common/math/FullMath.sol"; contract RewardsInternals is StakingStorage, IStakingEvents { // solhint-disable not-rely-on-time function _updateStreamsRewardsSchedules(uint256 streamId, uint256 rewardTokenAmount) internal { uint256 streamScheduleRewardLength = streams[streamId].schedule.reward.length; for (uint256 i; i < streamScheduleRewardLength; i++) { - streams[streamId].schedule.reward[i] = FullMath.mulDiv(streams[streamId].schedule.reward[i], rewardTokenAmount, streams[streamId].maxDepositAmount); + streams[streamId].schedule.reward[i] = (streams[streamId].schedule.reward[i] * rewardTokenAmount) / streams[streamId].maxDepositAmount; } } @@ -26,7 +26,8 @@ contract RewardsInternals is StakingStorage, IStakingEvents { require(streams[streamId].status == StreamStatus.ACTIVE, "inactive"); User storage userAccount = users[account]; require(lock.amountOfToken != 0, "No Stake"); - uint256 reward = FullMath.mulDiv((streams[streamId].rps - userAccount.rpsDuringLastClaimForLock[lockId][streamId]), lock.positionStreamShares, RPS_MULTIPLIER); + uint256 reward = ((streams[streamId].rps - userAccount.rpsDuringLastClaimForLock[lockId][streamId]) * lock.positionStreamShares) / + RPS_MULTIPLIER; if (reward == 0) return; // All rewards claimed or stream schedule didn't start userAccount.pendings[streamId] += reward; streamTotalUserPendings[streamId] += reward; diff --git a/contracts/dao/staking/packages/StakingGetters.sol b/contracts/dao/staking/packages/StakingGetters.sol index 4e8e5db..46011c4 100644 --- a/contracts/dao/staking/packages/StakingGetters.sol +++ b/contracts/dao/staking/packages/StakingGetters.sol @@ -27,15 +27,32 @@ contract StakingGetters is StakingStorage, IStakingGetter, StakingInternals { return ((latestRps - userRpsPerLock) * userSharesOfLock) / RPS_MULTIPLIER; } - function readBySlot(uint256 slot) external view override returns(bytes32 value) { - assembly { - value := sload(slot) - } - } + function getAllLocks(address account) external override view returns (LockedBalance[] memory) { return locks[account]; } function getStreamSchedule(uint256 streamId) external override view returns (uint256[] memory scheduleTimes, uint256[] memory scheduleRewards) { return (streams[streamId].schedule.time, streams[streamId].schedule.reward); } + + function getStream( + uint256 streamId + ) + external + view + returns ( + uint256 rewardDepositAmount, + uint256 rewardClaimedAmount, + uint256 rps, + StreamStatus status + ) + { + Stream storage stream = streams[streamId]; + return ( + stream.rewardDepositAmount, + stream.rewardClaimedAmount, + stream.rps, + stream.status + ); + } } diff --git a/coralX-config.js b/coralX-config.js index 2cee8e5..6d76713 100644 --- a/coralX-config.js +++ b/coralX-config.js @@ -36,9 +36,9 @@ module.exports = { optimizer: { enabled: true, details: { yul: false }, - runs: 200, + runs: 100, }, - evmVersion: 'istanbul', + evmVersion: 'london', }, }, }, From 95c5bc735907261308113253841bd5369289a247 Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 8 Feb 2023 13:00:47 +0545 Subject: [PATCH 54/77] blacklist a proposer --- contracts/dao/governance/Governor.sol | 10 +++- .../dao/governance/proposal-flow.test.js | 53 +++++++++++++++++++ 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 5cb301c..01941a4 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -41,6 +41,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { address private multiSig; uint256 public proposalLifetime; + mapping(address => bool) isBlacklisted; mapping(uint256 => ProposalCore) internal _proposals; mapping(uint256 => string) internal _descriptions; @@ -197,7 +198,8 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { ) public virtual override returns (uint256) { require(live == 1,"not live"); require(getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold"); - + + require(!isBlacklisted[msg.sender],"Proposer is blacklisted"); require(block.timestamp > nextAcceptableProposalTimestamp[msg.sender], "Governor: Can only submit one proposal for a certain interval"); nextAcceptableProposalTimestamp[msg.sender] = block.timestamp + proposalTimeDelay; @@ -265,6 +267,10 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { proposalLifetime = newProposalLifetime; } + function setBlacklistStatusForProposer(address account, bool blacklistStatus) public onlyMultiSig { + isBlacklisted[account] = blacklistStatus; + } + function _emergencyStop() internal { require(live == 1, "not-live"); live = 0; @@ -421,6 +427,8 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { return 0; } + + function hashProposal( address[] memory targets, uint256[] memory values, diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 53d8692..9a6e023 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -41,6 +41,24 @@ const _encodeEmergencyStop = () => { },[]); } +const _encodeBlacklistProposer = (_account,_blacklistStatus) =>{ + return web3.eth.abi.encodeFunctionCall( + { + name: 'setBlacklistStatusForProposer', + type: 'function', + inputs: [ + { + type: 'address', + name: 'account' + }, + { + type: 'bool', + name: 'blacklistStatus' + } + ] + },[_account,_blacklistStatus]); +} + const T_TO_STAKE = web3.utils.toWei('2000', 'ether'); const STAKED_MIN = web3.utils.toWei('1900', 'ether'); let streamReward1; @@ -1092,6 +1110,41 @@ describe('Proposal flow', () => { const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) }); + + it('Should blacklist a proposer', async() =>{ + const _blacklistAProposer = async(account, blacklistStatus) => { + const result = await multiSigWallet.submitTransaction( + mainTokenGovernor.address, + EMPTY_BYTES, + _encodeBlacklistProposer(account, blacklistStatus), + 0, + {"from": accounts[0]} + ) + + const tx = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(tx, {"from": accounts[0]}); + await multiSigWallet.confirmTransaction(tx, {"from": accounts[1]}); + await multiSigWallet.executeTransaction(tx, {"from": accounts[1]}); + } + + await _blacklistAProposer(accounts[5], true) + }) + + it('Should revert on propose by blacklisted msg.sender', async() =>{ + let errorMessage = "Proposer is blacklisted"; + + await shouldRevert( + mainTokenGovernor.propose( + [box.address], + [0], + [encoded_function], + PROPOSAL_DESCRIPTION, + {"from": accounts[5]} + ), + errTypes.revert, + errorMessage + ); + }) }); describe("Emergency Stop through multisig", async() => { From aae7325c3bd0c4028bd9f6978238f76f84206e76 Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 8 Feb 2023 19:43:27 +0545 Subject: [PATCH 55/77] require strings changes --- contracts/dao/governance/Governor.sol | 22 +++++++++---------- .../extensions/GovernorTimelockControl.sol | 6 ++--- .../GovernorVotesQuorumFraction.sol | 4 ++-- coralX-config.js | 4 ++-- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index 01941a4..c9d3dd5 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -52,7 +52,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { uint256 public constant MINIMUM_LIFETIME = 86400;//oneDay modifier onlyGovernance() { - require(_msgSender() == _executor(), "Governor: onlyGovernance"); + require(_msgSender() == _executor(), "onlyGovernance"); if (_executor() != address(this)) { bytes32 msgDataHash = keccak256(_msgData()); // loop until popping the expected operation - throw if deque is empty (operation not authorized) @@ -83,7 +83,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { uint256 proposalTimeDelay_, uint256 proposalLifetime_ ) EIP712(name_, version()) { - require(multiSig_ != address(0), "multiSig address cant be zero address"); + require(multiSig_ != address(0), "multiSig zero address"); require(maxTargets_ != 0, "maxTarget cant be zero"); require(proposalTimeDelay_ != 0, "proposalTimeDelay cant be zero"); require(proposalLifetime_ >= MINIMUM_LIFETIME,"lifetime less than minimum"); @@ -116,7 +116,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { for (uint256 i = 0; i < values.length; i++) { totalValue += values[i]; } - require(msg.value >= totalValue, "execute: msg.value not sufficient"); + require(msg.value >= totalValue, "msg.value not sufficient"); _proposals[proposalId].executed = true; emit ProposalExecuted(proposalId); @@ -197,10 +197,10 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { string memory description ) public virtual override returns (uint256) { require(live == 1,"not live"); - require(getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), "Governor: proposer votes below proposal threshold"); + require(getVotes(_msgSender(), block.number - 1) >= proposalThreshold(), "Governor: proposer votes below threshold"); require(!isBlacklisted[msg.sender],"Proposer is blacklisted"); - require(block.timestamp > nextAcceptableProposalTimestamp[msg.sender], "Governor: Can only submit one proposal for a certain interval"); + require(block.timestamp > nextAcceptableProposalTimestamp[msg.sender], "Can submit in interval"); nextAcceptableProposalTimestamp[msg.sender] = block.timestamp + proposalTimeDelay; @@ -233,7 +233,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { requireNotExpired(_proposalId); isConfirmed[_proposalId] = true; ProposalState status = state(_proposalId); - require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); + require(status == ProposalState.Succeeded || status == ProposalState.Queued, "proposal not successful"); emit ConfirmProposal(msg.sender, _proposalId); } @@ -244,25 +244,25 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { } function updateMultiSig(address newMultiSig) public onlyMultiSig { - require(newMultiSig != address(0), "updateMultiSig: newMultiSig cant be set to zero address"); + require(newMultiSig != address(0), "zero address"); emit MultiSigUpdated(newMultiSig, multiSig); multiSig = newMultiSig; } function updateMaxTargets(uint256 newMaxTargets) public onlyMultiSig { - require(newMaxTargets != 0, "updateMaxTargets: newMaxTargets cant be zero"); + require(newMaxTargets != 0, "zero value"); emit MaxTargetUpdated(newMaxTargets, maxTargets); maxTargets = newMaxTargets; } function updateProposalTimeDelay(uint256 newProposalTimeDelay) public onlyMultiSig { - require(newProposalTimeDelay != 0, "updateProposalTimeDelay: newProposalTimeDelay cant be zero"); + require(newProposalTimeDelay != 0, "zero value"); emit ProposalTimeDelayUpdated(newProposalTimeDelay, proposalTimeDelay); proposalTimeDelay = newProposalTimeDelay; } function updateProposalLifetime(uint256 newProposalLifetime) public onlyMultiSig { - require(newProposalLifetime>= MINIMUM_LIFETIME, "updateProposalLifetime: updateProposalLifetime less than minimum"); + require(newProposalLifetime>= MINIMUM_LIFETIME, "less than minimum"); emit ProposalLifetimeUpdated(newProposalLifetime, newProposalLifetime); proposalLifetime = newProposalLifetime; } @@ -526,7 +526,7 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { bytes memory params ) internal virtual returns (uint256) { ProposalCore storage proposal = _proposals[proposalId]; - require(state(proposalId) == ProposalState.Active, "Governor: vote not currently active"); + require(state(proposalId) == ProposalState.Active, "Governor: vote inactive"); uint256 weight = _getVotes(account, proposal.voteStart.getDeadline(), params); _countVote(proposalId, account, support, weight, params); diff --git a/contracts/dao/governance/extensions/GovernorTimelockControl.sol b/contracts/dao/governance/extensions/GovernorTimelockControl.sol index 8b0c5b7..834750d 100644 --- a/contracts/dao/governance/extensions/GovernorTimelockControl.sol +++ b/contracts/dao/governance/extensions/GovernorTimelockControl.sol @@ -15,7 +15,7 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { event TimelockChange(address oldTimelock, address newTimelock); constructor(TimelockController timelockAddress) { - require(address(timelockAddress) != address(0), "timelockAddress cant be zero address"); + require(address(timelockAddress) != address(0), "timelockAddress: zero address"); _updateTimelock(timelockAddress); } @@ -83,7 +83,7 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { bytes[] memory calldatas, bytes32 descriptionHash ) internal virtual override { - require(!isProposalExecuted[proposalId], "_execute: proposal already executed"); + require(!isProposalExecuted[proposalId], "_execute: already executed"); _timelock.executeBatch{ value: msg.value }(targets, values, calldatas, 0, descriptionHash); isProposalExecuted[proposalId] = true; } @@ -112,7 +112,7 @@ abstract contract GovernorTimelockControl is IGovernorTimelock, Governor { } function _updateTimelock(TimelockController newTimelock) private { - require(address(newTimelock) != address(0), "updateTimelock: newTimelock address cannot be zero address"); + require(address(newTimelock) != address(0), "updateTimelock: zero address"); emit TimelockChange(address(_timelock), address(newTimelock)); _timelock = newTimelock; } diff --git a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol b/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol index 05af064..d6ae31e 100644 --- a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol +++ b/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol @@ -53,8 +53,8 @@ abstract contract GovernorVotesQuorumFraction is GovernorVotes { } function _updateQuorumNumerator(uint256 newQuorumNumerator) internal virtual { - require(newQuorumNumerator <= quorumDenominator(), "GovernorVotesQuorumFraction: quorumNumerator over quorumDenominator"); - require(newQuorumNumerator >= MINIMUM_QUORUM_NUMERATOR, "GovernorVotesQuorumFraction: quorumNumerator less than Minimum"); + require(newQuorumNumerator <= quorumDenominator(), "quorumNumerator over quorumDenominator"); + require(newQuorumNumerator >= MINIMUM_QUORUM_NUMERATOR, "quorumNumerator less than Minimum"); uint256 oldQuorumNumerator = _quorumNumerator; _quorumNumerator = newQuorumNumerator; diff --git a/coralX-config.js b/coralX-config.js index 6d76713..2cee8e5 100644 --- a/coralX-config.js +++ b/coralX-config.js @@ -36,9 +36,9 @@ module.exports = { optimizer: { enabled: true, details: { yul: false }, - runs: 100, + runs: 200, }, - evmVersion: 'london', + evmVersion: 'istanbul', }, }, }, From 471d8fca13d7bffda0322144b4ffd3afd2ad7438 Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 8 Feb 2023 19:46:00 +0545 Subject: [PATCH 56/77] test fixes --- scripts/tests/dao/governance/proposal-flow.test.js | 4 ++-- .../tests/dao/governance/token-creation-though-gov.test.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 9a6e023..1f5d51f 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -284,7 +284,7 @@ describe('Proposal flow', () => { it('Should revert proposal if: proposer votes below proposal threshold', async() => { - let errorMessage = "Governor: proposer votes below proposal threshold"; + let errorMessage = "Governor: proposer votes below threshold"; await shouldRevert( mainTokenGovernor.propose( @@ -565,7 +565,7 @@ describe('Proposal flow', () => { it("Should not accept votes outside of the voting period", async () => { - const errorMessage = "Governor: vote not currently active"; + const errorMessage = "Governor: vote inactive"; await shouldRevert( mainTokenGovernor.castVote(proposalId2, "1", {"from": STAKER_1}), diff --git a/scripts/tests/dao/governance/token-creation-though-gov.test.js b/scripts/tests/dao/governance/token-creation-though-gov.test.js index 941494d..459dc85 100644 --- a/scripts/tests/dao/governance/token-creation-though-gov.test.js +++ b/scripts/tests/dao/governance/token-creation-though-gov.test.js @@ -209,7 +209,7 @@ describe('Token Creation Through Governance', () => { it('Should revert proposal if: proposer votes below proposal threshold', async() => { - let errorMessage = "Governor: proposer votes below proposal threshold"; + let errorMessage = "Governor: proposer votes below threshold"; await shouldRevert( mainTokenGovernor.propose( From e76058df9ca2fe682534026981c6e3522b953ad0 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 9 Feb 2023 12:30:16 +0545 Subject: [PATCH 57/77] reducing contract size --- contracts/dao/staking/StakingStorage.sol | 12 +++---- .../staking/interfaces/IStakingHandler.sol | 2 +- .../dao/staking/packages/StakingHandler.sol | 32 +++++++++++++------ .../dao/staking/packages/StakingInternals.sol | 11 +++++-- 4 files changed, 38 insertions(+), 19 deletions(-) diff --git a/contracts/dao/staking/StakingStorage.sol b/contracts/dao/staking/StakingStorage.sol index fbffcf4..a3cdd24 100644 --- a/contracts/dao/staking/StakingStorage.sol +++ b/contracts/dao/staking/StakingStorage.sol @@ -12,15 +12,15 @@ contract StakingStorage { //Set according to Tokenomics: Max Supply: 1e9 * 1e18, weight = 1e3, tolerance for changes = 6, so 1e36 uint256 internal constant RPS_MULTIPLIER = 1e36; uint128 internal constant POINT_MULTIPLIER = 1e18; - uint64 internal constant ONE_MONTH = 2629746; - uint64 internal constant ONE_YEAR = 31536000; + uint32 internal constant ONE_MONTH = 2629746; + uint32 internal constant ONE_YEAR = 31536000; + uint32 internal constant ONE_DAY = 86400; //MAX_LOCK: It is a constant. One WEEK Added as a tolerance. uint256 public maxLockPeriod; ///@notice Checks if the staking is initialized - uint256 public maxLockPositions; - mapping(address => mapping(uint256 => bool)) public prohibitedEarlyWithdraw; + mapping(address => mapping(uint256 => bool)) internal prohibitedEarlyWithdraw; uint256 internal touchedAt; @@ -41,8 +41,8 @@ contract StakingStorage { address public voteToken; address public vault; address public rewardsCalculator; - bool public councilsInitialized; - bool public mainStreamInitialized; + bool internal councilsInitialized; + bool internal mainStreamInitialized; ///Weighting coefficient for shares and penalties Weight public weight; diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index dab4f55..334f723 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -16,7 +16,7 @@ interface IStakingHandler { Weight calldata _weight, VoteCoefficient memory voteCoef, uint256 _maxLocks, - address _rewardsContract + address _rewardsContract, ) external; function initializeMainStream( diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index b4bf158..cefc397 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -16,11 +16,14 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A bytes32 public constant STREAM_MANAGER_ROLE = keccak256("STREAM_MANAGER_ROLE"); bytes32 public constant TREASURY_ROLE = keccak256("TREASURY_ROLE"); - error LockLengthExceeded(uint256 _lockId, address _account); error NotPaused(); error VaultNotSupported(address _vault); error VaultNotMigrated(address _vault); error ZeroLockId(); + error MaxLockIdExceeded(uint256 _lockId, address _account); + error ZeroPenalty(); + error AlreadyInitialized(); + error StreamIdZero(); constructor() { _disableInitializers(); } @@ -43,7 +46,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A Weight calldata _weight, VoteCoefficient calldata voteCoef, uint256 _maxLocks, - address _rewardsContract + address _rewardsContract, ) external override initializer { rewardsCalculator = _rewardsContract; _initializeStaking(_mainToken, _voteToken, _weight, _vault, _maxLocks, voteCoef.voteShareCoef, voteCoef.voteLockCoef); @@ -60,7 +63,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A uint256[] memory scheduleRewards, uint256 tau ) external override onlyRole(DEFAULT_ADMIN_ROLE){ - require(!mainStreamInitialized,"init done"); + if(mainStreamInitialized == true){ + revert AlreadyInitialized(); + } IERC20(mainToken).safeTransferFrom(msg.sender,address(this),scheduleRewards[0]); _validateStreamParameters(_owner, mainToken, scheduleRewards[MAIN_STREAM], scheduleRewards[MAIN_STREAM], scheduleTimes, scheduleRewards, tau); uint256 streamId = 0; @@ -166,7 +171,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } function removeStream(uint256 streamId, address streamFundReceiver) public override onlyRole(STREAM_MANAGER_ROLE) { - require(streamId != 0, "Stream 0"); + if(streamId == 0){ + revert StreamIdZero(); + } require(streamTotalUserPendings[streamId] == 0, "nt withdrawn"); Stream storage stream = streams[streamId]; require(stream.status == StreamStatus.ACTIVE, "No Stream"); @@ -183,7 +190,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } function createLocksForCouncils(CreateLockParams[] calldata lockParams) public override onlyRole(DEFAULT_ADMIN_ROLE) { - require(!councilsInitialized, "created"); + if(councilsInitialized == true){ + revert AlreadyInitialized(); + } councilsInitialized = true; for (uint256 i; i < lockParams.length; i++) { address account = lockParams[i].account; @@ -227,9 +236,11 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A function claimAllStreamRewardsForLock(uint256 lockId) public override pausable(1) { if(lockId > locks[msg.sender].length){ - revert LockLengthExceeded(lockId, msg.sender); + revert MaxLockIdExceeded(lockId, msg.sender); + } + if(lockId == 0){ + revert ZeroLockId(); } - require(lockId != 0, "lockId 0"); _updateStreamRPS(); // Claim all streams while skipping inactive streams. _moveAllStreamRewardsToPending(msg.sender, lockId); @@ -290,7 +301,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } function withdrawPenalty(address penaltyReceiver) public override pausable(1) onlyRole(TREASURY_ROLE) { - require(totalPenaltyBalance > 0, "no penalty"); + if(totalPenaltyBalance == 0){ + revert ZeroPenalty(); + } _withdrawPenalty(penaltyReceiver); } @@ -313,10 +326,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A revert ZeroLockId(); } if(lockId > locks[msg.sender].length){ - revert LockLengthExceeded(lockId, msg.sender); + revert MaxLockIdExceeded(lockId, msg.sender); } LockedBalance storage lock = locks[msg.sender][lockId - 1]; - require(lock.amountOfToken != 0,"zeroLocked"); require(lock.owner == msg.sender, "bad owner"); } diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 45dffd0..4c29cfc 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -16,6 +16,8 @@ import "../../../common/math/FullMath.sol"; contract StakingInternals is RewardsInternals { // solhint-disable not-rely-on-time error ZeroAddress(); + error ZeroLocked(uint256 lockId); + error ZeroTotalToken(); function _initializeStaking( address _mainToken, address _voteToken, @@ -93,8 +95,13 @@ contract StakingInternals is RewardsInternals { ) internal { User storage userAccount = users[account]; LockedBalance storage updateLock = locks[account][lockId - 1]; - require(totalAmountOfStakedToken !=0, "zeroTotal"); - require(updateLock.amountOfToken !=0,"zeroLocked"); + if(updateLock.amountOfToken == 0){ + revert ZeroLocked(lockId); + } + if(totalAmountOfStakedToken == 0){ + revert ZeroTotalToken(); + } + uint256 nVoteToken = updateLock.amountOfVoteToken; /// if you unstake, early or partial or complete, /// the number of vote tokens for lock position is set to zero From a278c8fc1e9bd3fa952e682e8c926886e88dd40b Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 9 Feb 2023 12:36:15 +0545 Subject: [PATCH 58/77] compilation error fixed --- contracts/dao/staking/interfaces/IStakingHandler.sol | 2 +- contracts/dao/staking/packages/StakingHandler.sol | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index 334f723..dab4f55 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -16,7 +16,7 @@ interface IStakingHandler { Weight calldata _weight, VoteCoefficient memory voteCoef, uint256 _maxLocks, - address _rewardsContract, + address _rewardsContract ) external; function initializeMainStream( diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index cefc397..3e6a2a2 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -46,7 +46,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A Weight calldata _weight, VoteCoefficient calldata voteCoef, uint256 _maxLocks, - address _rewardsContract, + address _rewardsContract ) external override initializer { rewardsCalculator = _rewardsContract; _initializeStaking(_mainToken, _voteToken, _weight, _vault, _maxLocks, voteCoef.voteShareCoef, voteCoef.voteLockCoef); From 642903543fe51f8ab2bf09d139ac886a6a3497a1 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 9 Feb 2023 12:43:10 +0545 Subject: [PATCH 59/77] added min lock criteria --- contracts/dao/staking/StakingStorage.sol | 3 +++ .../staking/interfaces/IStakingHandler.sol | 1 + .../dao/staking/packages/StakingHandler.sol | 11 ++++++++ .../prod/1_deploy_init_staking_proxy.js | 7 +++++- .../test/2_deploy_init_staking_proxy.js | 8 ++++-- scripts/tests/dao/staking/staking.test.js | 25 ++++++++++++------- 6 files changed, 43 insertions(+), 12 deletions(-) diff --git a/contracts/dao/staking/StakingStorage.sol b/contracts/dao/staking/StakingStorage.sol index a3cdd24..fcb00ef 100644 --- a/contracts/dao/staking/StakingStorage.sol +++ b/contracts/dao/staking/StakingStorage.sol @@ -19,6 +19,9 @@ contract StakingStorage { uint256 public maxLockPeriod; ///@notice Checks if the staking is initialized + + uint256 public minLockPeriod; + uint256 public maxLockPositions; mapping(address => mapping(uint256 => bool)) internal prohibitedEarlyWithdraw; diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index 334f723..a4fca2b 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -17,6 +17,7 @@ interface IStakingHandler { VoteCoefficient memory voteCoef, uint256 _maxLocks, address _rewardsContract, + uint256 _minLockPeriod ) external; function initializeMainStream( diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index cefc397..9faaaf1 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -20,6 +20,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A error VaultNotSupported(address _vault); error VaultNotMigrated(address _vault); error ZeroLockId(); + error MaxLockPeriodExceeded(); error MaxLockIdExceeded(uint256 _lockId, address _account); error ZeroPenalty(); error AlreadyInitialized(); @@ -47,6 +48,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A VoteCoefficient calldata voteCoef, uint256 _maxLocks, address _rewardsContract, + uint256 _minLockPeriod ) external override initializer { rewardsCalculator = _rewardsContract; _initializeStaking(_mainToken, _voteToken, _weight, _vault, _maxLocks, voteCoef.voteShareCoef, voteCoef.voteLockCoef); @@ -55,6 +57,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _grantRole(STREAM_MANAGER_ROLE, _admin); _grantRole(TREASURY_ROLE, _admin); maxLockPeriod = ONE_YEAR; + minLockPeriod = _minLockPeriod; } function initializeMainStream( @@ -312,6 +315,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A uint256 lockPeriod, address account ) internal{ + require(lockPeriod >= minLockPeriod, "min lock"); require(locks[account].length <= maxLockPositions, "max locks"); require(amount > 0, "amount 0"); require(lockPeriod <= maxLockPeriod, "max time"); @@ -337,4 +341,11 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A IERC20(_token).safeApprove(vault,_amount); IVault(vault).deposit(_token, _amount); } + + function setMinimumLockPeriod(uint256 _minLockPeriod) public onlyRole(DEFAULT_ADMIN_ROLE){ + if(_minLockPeriod > maxLockPeriod){ + revert MaxLockPeriodExceeded(); + } + minLockPeriod = _minLockPeriod; + } } diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index 9b9d697..87ebfe4 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -48,6 +48,7 @@ const maxWeightPenalty = 3000; const minWeightPenalty = 100; const weightMultiplier = 10; const maxNumberOfLocks = 10; +const minimumLockingPeriod = 4 * 86400; const lockingVoteWeight = 365 * 24 * 60 * 60; @@ -115,9 +116,13 @@ module.exports = async function(deployer) { { type: 'address', name: '_rewardsContract' + }, + { + type: 'uint256', + name: '_minLockPeriod' }] }, [MultiSigWallet.address, vaultService.address, MainToken.address, VMainToken.address, - weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address]); + weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address, minimumLockingPeriod]); await deployer.deploy(StakingProxyAdmin, {gas:8000000}); await deployer.deploy(StakingProxy, StakingPackage.address, StakingProxyAdmin.address, toInitialize, {gas:8000000}); diff --git a/scripts/migrations/test/2_deploy_init_staking_proxy.js b/scripts/migrations/test/2_deploy_init_staking_proxy.js index fc74366..39aa0dc 100644 --- a/scripts/migrations/test/2_deploy_init_staking_proxy.js +++ b/scripts/migrations/test/2_deploy_init_staking_proxy.js @@ -13,7 +13,7 @@ const IVault = artifacts.require('./dao/staking/vault/interfaces/IVault.sol'); const StakingProxyAdmin = artifacts.require('./common/proxy/StakingProxyAdmin.sol'); const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') - +const minimumLockingPeriod = 5; const _createWeightObject = ( maxWeightShares, minWeightShares, @@ -120,9 +120,13 @@ module.exports = async function(deployer) { { type: 'address', name: '_rewardsContract' + }, + { + type: 'uint256', + name: '_minLockPeriod' }] }, [MultiSigWallet.address, vaultService.address, MainToken.address, VMainToken.address, - weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address]); + weightObject, voteObject, maxNumberOfLocks, RewardsCalculator.address,minimumLockingPeriod]); await deployer.deploy(StakingProxyAdmin, {gas:8000000}); await deployer.deploy(StakingProxy, StakingPackage.address, StakingProxyAdmin.address, toInitialize, {gas:8000000}); diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index 2cc584d..7ce7420 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -428,7 +428,6 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + 20); let result3 = await stakingService.createLock(sumToDepositForAll,unlockTime, {from: staker_4}); await blockchain.mineBlock(await _getTimeStamp() + 20); - let eventArgs1 = eventsHelper.getIndexedEventArgs(result1, "Staked(address,uint256,uint256,uint256,uint256,uint256)"); let eventArgs2 = eventsHelper.getIndexedEventArgs(result2, "Staked(address,uint256,uint256,uint256,uint256,uint256)"); let eventArgs3 = eventsHelper.getIndexedEventArgs(result3, "Staked(address,uint256,uint256,uint256,uint256,uint256)"); @@ -953,6 +952,8 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + mineToTimestamp); }) + + it("Should get all unlocked main token for staker - 3", async() => { // When we unlock, the main token should be sent to stream 0, with users stream id. // Once unlocked, the token is available for withdrawl from stream 0 to staker - 3. @@ -1130,13 +1131,13 @@ describe("Staking Test", () => { it('Setup lock position for accounts[9] for govn to use', async() => { const sumToApprove = web3.utils.toWei('20000','ether'); - + await FTHMToken.approve(stakingService.address, sumToApprove, {from: accounts[9]}) - const lockingPeriod = 365 * 24 * 60 * 60 - const unlockTime = lockingPeriod; - - const sumToDeposit = web3.utils.toWei('20000', 'ether'); - let result1 = await stakingService.createLock(sumToDeposit,unlockTime, {from: accounts[9], gas: maxGasForTxn}); + const lockingPeriod = 364 * 24 * 60 * 60 + await blockchain.mineBlock(await _getTimeStamp() + 100); + const sumToDeposit = web3.utils.toWei('200', 'ether'); + let result1 = await stakingService.createLock(sumToDeposit,lockingPeriod, {from: accounts[9], gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); }) it("Should get correct user total votes from staking getter service", async() => { @@ -1180,10 +1181,15 @@ describe("Staking Test", () => { assert(totalPenaltyBalance.toString(),"0") }) - it('Should should make lock position with 0 lock period', async() => { + it('Should not make lock position with 0 lock period', async() => { const unlockTime = 0; await blockchain.mineBlock(await _getTimeStamp() + 100); - let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}); + const errorMessage = "min lock" + await shouldRevert( + stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}), + errTypes.revert, + errorMessage + ); await blockchain.mineBlock(await _getTimeStamp() + 100); }) @@ -1221,6 +1227,7 @@ describe("Staking Test", () => { errorMessage ); }) + it('Unpaused contract should make lock position', async() => { const toUnPauseFlag = 0 From d807135ab968556cac368f13f206df664753fd76 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 9 Feb 2023 13:54:58 +0545 Subject: [PATCH 60/77] reverting fix for now --- audit-report/Fathom_DAO-review.md | 26 +++++++++---------- contracts/dao/governance/Governor.sol | 4 ++- .../dao/governance/TimelockController.sol | 2 +- contracts/dao/treasury/MultiSigWallet.sol | 10 ++++--- 4 files changed, 23 insertions(+), 19 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 4f5c647..005b73a 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -143,7 +143,7 @@ Implemented Auditors Recommendation. with slight change: changeRequirement(numConfirmationsRequired + _owners.length); ``` -#### 1. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE -ASK Anton - ask auditor, does it require to revoke confirmation in submitTransaction, TODAY] +#### 1. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE -ASK Anton - ask auditor, does it require to revoke confirmation in executeTransaction, TODAY] ##### Description In the function [`removeOwner`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L96) the owner is being removed without revocation of transaction signatures, where they've signed. This creates a situation where the signatures of non-existent owners may be used. For example, like in the following scenario: @@ -180,7 +180,7 @@ We recommend adding logic that would allow you to cancel the execution of `propo ###### Fathom's response Implemented Auditors Recommendation. -#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE - ASK AUDITOR] +#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE - ASK AUDITOR-Verified] ##### Description A change of the `timelock` parameter in the [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L22) contract can lead to already executed `proposals` being able to be executed again. This is connected to the fact that the execution status of the transaction is saved only in the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, and the `GovernorTimelockControl` contract makes calls to the `TimelockController` functions to get the `proposals` status in the [`state`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L50) function. ##### Recommendation @@ -346,7 +346,7 @@ We recommend adding a constant with the minimum allowable value of `_quorumNumer Implemented Auditors Recommendation. -#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE - Ask Auditor] +#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE - Ask Auditor- VERIFIEd] ##### Description In the [VMainToken](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) contract, for mint tokens, calling account, in addition to having `MINTER_ROLE` rights, must also be in the `isWhiteListed` list, since the mint function calls `_mint,` which contains [`_beforeTokenTransfer`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65) call. When `_beforeTokenTransfer` is called, it checks that the `msg.sender` address is in the `isWhiteListed` list. @@ -419,7 +419,7 @@ We recommend making two different functions for relaying `ERC20` tokens and nati -#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor -> Do we need to have not migrated check in withdraw Extra supported tokens?] +#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor -> VERIFIED] ##### Description The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol) contract lacks the ability to suspend a contract in an emergency and migrate assets to a new compatible `VaultPackage` contract. @@ -487,7 +487,7 @@ We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppeli ###### Fathom's response Implemented Auditors Recommendation. -#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE , Ask Auditor] +#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE , VERIFIED] ##### Description In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. @@ -506,7 +506,7 @@ Recommendation has not been fully implemented. In the current version there is s We recommend adding a separate withdraw function, that would allow the `DEFAULT_ADMIN_ROLE` address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). -#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE - Ask Auditor] +#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE - Ask Auditor -VERFIED] ##### Description In the `StakingHandlers` contract the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function does not allocate tokens for rewards `MAIN_STREAM`, as it happens when [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) is called. This may result in the block of the `withdrawStream` function call from the `MAIN_STREAM` of tokens and rewards for some users, if the amount in `VaultPackage` is less than the amount stated in `scheduleRewards`. ##### Recommendation @@ -565,7 +565,7 @@ bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); ###### Fathom's response Implemented Auditors Recommendation. -#### 5. [NEW] Transaction should be marked as `executed` if the call fails[DONE Ask Auditor -NOTDONE, check again] +#### 5. [NEW] Transaction should be marked as `executed` if the call fails[DONE Ask Auditor -NOTDONE, check again ---!!!!!! TODO] ##### Description @@ -624,7 +624,7 @@ We recommend: ###### Fathom's response Implemented Auditors Recommendation. -#### 14 .[NEW] `prohibitedEarlyWithdraw` is not set to `false` for `lockid` after unlocking in `StakingHandlers`[DONE] +#### 14 .[NEW] `prohibitedEarlyWithdraw` is not set to `false` for `lockid` after unlocking in `StakingHandlers`[DONE -VERIFIED] ##### Description In the function [`createLockWithoutEarlyWithdraw`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L181) in the `StakingHandlers` contract parameter `prohibitedEarlyWithdraw` for given `lockid` is set to `true`, but it does not update to `false` after unlocking later in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions. Since the value in the `locks` array is deleted after the unlock, all new values will be assigned the value of `prohibitedEarlyWithdraw`, regardless of whether the `createLockWithoutEarlyWithdraw` or `createLock` function is called. @@ -705,7 +705,7 @@ return ###### Fathom's response Implemented Auditors Recommendation. -#### 15. [NEW] Penalty can be bigger than stake in the `StakingInternals`[DONE] +#### 15. [NEW] Penalty can be bigger than stake in the `StakingInternals`[DONE -VERIFIED] ##### Description @@ -781,7 +781,7 @@ We recommend removing `Governance` from this modifier and give the permission to ###### Fathom's response Thats the way its designed -#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[DONE - Ask Auditor TODAY] +#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[DONE - Ask Auditor VERIFIED] ##### Description In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. Based on the logic of the contract, there may be the following cases: @@ -845,7 +845,7 @@ In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom- ##### Recommendation We recommend adding balance check while adding a transaction with a non-zero value `_value`. -#### [NEW] There is no time limit for executing proposal in `Governor`[Ask ANTON -DONE Ask Auditor] +#### [NEW] There is no time limit for executing proposal in `Governor`[Ask ANTON -DONE Ask VERFIED] ##### Description The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract has no parameters for the time limit on `proposal` execution. This can result in no longer relevant proposal being executed after a period of time. ##### Recommendation @@ -881,7 +881,7 @@ require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Go ###### Fathom's response Implemented Auditors Recommendation. -#### 17. [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[DONE] +#### 17. [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[DONE - ASK AUDITOR TODAY -VERIFIED] ##### Description In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) contracts the `execute` functions do not check the `msg.value` balance value needed to execute `_targets`, which would result in gas consumption even if the amount of `ETH` is not enough. ##### Recommendation @@ -917,7 +917,7 @@ We recommend adding a check that `newProposalThreshold` is not zero. ###### Fathom's response Implemented Auditors Recommendation. -#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE, Ask Anton - Ask Auditor -TODAY!] +#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE, TODO - Added Blacklist, verified] ##### Description In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. ##### Recommendation diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index c9d3dd5..ce9d5ca 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -454,8 +454,10 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { bytes32 /*descriptionHash*/ ) internal virtual { for (uint256 i = 0; i < targets.length; ++i) { + string memory errorMessage = "Governor: call reverted without message"; (bool success, bytes memory returndata) = targets[i].call{ value: values[i] }(calldatas[i]); - emit ExecuteTransaction(msg.sender, success, returndata); + //emit ExecuteTransaction(msg.sender, success, returndata); + Address.verifyCallResult(success, returndata, errorMessage); } } diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index 0a68c71..f44f55c 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -239,7 +239,7 @@ contract TimelockController is AccessControl, Initializable, ITimelockController bytes memory data ) internal virtual { (bool success, ) = target.call{ value: value }(data); - emit ExecuteTransaction(msg.sender,success, data); + require(success, "TimelockController: underlying transaction reverted"); } function _afterCall(bytes32 id) private { diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index fece51d..86d10b8 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -221,11 +221,13 @@ contract MultiSigWallet is IMultiSigWallet { transaction.executed = true; - (bool success, ) = transaction.to.call{ value: transaction.value }(transaction.data); + (bool success, bytes memory data) = transaction.to.call{ value: transaction.value }(transaction.data); - require(success, "tx failed"); - - emit ExecuteTransaction(msg.sender, _txIndex); + if (success) { + emit ExecuteTransaction(msg.sender, _txIndex); + } else { + revert TransactionRevered(data); + } } function revokeConfirmation(uint256 _txIndex) From 4dd8b408662f6a3b61360245e99116bc9c83a259 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 9 Feb 2023 14:12:06 +0545 Subject: [PATCH 61/77] init main stream check with new contracts --- scripts/migrations/prod/5_init_main_stream.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/scripts/migrations/prod/5_init_main_stream.js b/scripts/migrations/prod/5_init_main_stream.js index 964d38f..b9c5e87 100644 --- a/scripts/migrations/prod/5_init_main_stream.js +++ b/scripts/migrations/prod/5_init_main_stream.js @@ -8,7 +8,7 @@ const EMPTY_BYTES = '0x000000000000000000000000000000000000000000000000000000000 const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') - +const ExecuteTransactionSuccess = "ExecuteTransaction(address,uint256)" const _encodeApproveFunction = (_account, _amount) => { let toRet = web3.eth.abi.encodeFunctionCall({ name: 'approve', @@ -54,7 +54,7 @@ const tau = 60; module.exports = async function(deployer) { // const startTime = 1675526400 //EIGHT_PM_UAE_TIME_FEB_FOUR_Timestamp - const startTime = 1675756800 //TWELVE_PM_UAE_TIME_FEB_SEVEN_Timestamp + const startTime = 1678328872 //TWELVE_PM_UAE_TIME_FEB_SEVEN_Timestamp const oneDay = 86400; const scheduleTimes = [ startTime, @@ -110,5 +110,6 @@ module.exports = async function(deployer) { let txIndexInit = eventsHelper.getIndexedEventArgs(resultInit, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexInit, {gas: 8000000}); const resultOfInitMainStream = await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); - //const successStatusInitMainStream = eventsHelper.getIndexedEventArgs(resultOfInitMainStream, ExecuteTransactionSuccess); + const successStatusInitMainStream = eventsHelper.getIndexedEventArgs(resultOfInitMainStream, ExecuteTransactionSuccess); + console.log(successStatusInitMainStream) } From 2439039cf72f01e1cd21c5a959a635e98033af5a Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 9 Feb 2023 15:16:49 +0545 Subject: [PATCH 62/77] lock amount of token --- contracts/dao/staking/packages/StakingHandler.sol | 3 +++ 1 file changed, 3 insertions(+) diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 9faaaf1..9edcbe8 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -334,6 +334,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } LockedBalance storage lock = locks[msg.sender][lockId - 1]; require(lock.owner == msg.sender, "bad owner"); + if(lock.amountOfToken == 0){ + revert ZeroLocked(lockId); + } } function _transfer(uint256 _amount, address _token) internal{ From 1a0acb71a45d19ae06b711fa3e10e73463406203 Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 9 Feb 2023 16:44:58 +0545 Subject: [PATCH 63/77] fixing multisig loop and tests --- audit-report/Fathom_DAO-review.md | 2 +- contracts/dao/governance/interfaces/IGovernor.sol | 1 - .../dao/staking/interfaces/IStakingHandler.sol | 1 - contracts/dao/treasury/MultiSigWallet.sol | 4 ++-- scripts/tests/dao/governance/proposal-flow.test.js | 14 +++++++------- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index 005b73a..b99aef1 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -303,7 +303,7 @@ We recommend adding the `updateMultisig` function, but so that only the old `mul ###### Fathom's response Implemented Auditors Recommendation. -#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE -> ASK AUDITOR FOR HELP, TODAY ASK AUDITOR-Verified] +#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE -> ASK AUDITOR FOR HELP, TODAY ASK AUDITOR-Verified. AGAINVERIFY] ##### Description There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. ##### Recommendation diff --git a/contracts/dao/governance/interfaces/IGovernor.sol b/contracts/dao/governance/interfaces/IGovernor.sol index eb3b6da..a3a2e27 100644 --- a/contracts/dao/governance/interfaces/IGovernor.sol +++ b/contracts/dao/governance/interfaces/IGovernor.sol @@ -131,7 +131,6 @@ abstract contract IGovernor is IERC165 { ) public view virtual returns (uint256); function hasVoted(uint256 proposalId, address account) public view virtual returns (bool); - /** * @dev A description of the possible `support` values for {castVote} and the way these votes are counted, meant to * be consumed by UIs to show correct vote options and interpret the results. The string is a URL-encoded diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index dab4f55..672612d 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -59,7 +59,6 @@ interface IStakingHandler { function withdrawAllStreams() external; function withdrawPenalty(address penaltyReceiver) external; - function updateVault(address _vault) external; function emergencyUnlockAndWithdraw() external; diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 86d10b8..9fd6ef5 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -132,8 +132,8 @@ contract MultiSigWallet is IMultiSigWallet { uint256 nConfirmedTxnByOwner = confirmedTransactionsByOwner[owner].length(); - for(uint i = nConfirmedTxnByOwner; i >1; i--){ - uint256 _txIndex = confirmedTransactionsByOwner[owner].at(i-1); + for(uint i = 0; i < nConfirmedTxnByOwner; i++){ + uint256 _txIndex = confirmedTransactionsByOwner[owner].at(i); Transaction storage transaction = transactions[_txIndex]; transaction.numConfirmations -= 1; confirmedTransactionsByOwner[owner].remove(_txIndex); diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 1f5d51f..0c56e43 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -19,7 +19,7 @@ const AMOUNT_OUT_TREASURY = "1000"; // Events const PROPOSAL_CREATED_EVENT = "ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)" const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const EXECUTE_TRANSACTION_EVENT = "ExecuteTransaction(address,bool,bytes)"; +const EXECUTE_TRANSACTION_EVENT = "ExecuteTransaction(address,bool)"; const _encodeConfirmation = async (_proposalId) => { return web3.eth.abi.encodeFunctionCall({ @@ -810,8 +810,8 @@ describe('Proposal flow', () => { description_hash, {"from": accounts[0]} ); - const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; - expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) + // const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; + // expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) }); /// ------------- Relay Token -------/// it('Propose to add relay Token to other address', async() => { @@ -956,8 +956,8 @@ describe('Proposal flow', () => { } ); - const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; - expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) + // const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; + // expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) }); //relay ETH @@ -1107,8 +1107,8 @@ describe('Proposal flow', () => { } ); - const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; - expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) + // const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; + // expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) }); it('Should blacklist a proposer', async() =>{ From 038e0f5ab9a42ded45ee35ca4badd79b9c09f35d Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 9 Feb 2023 20:17:28 +0545 Subject: [PATCH 64/77] emergency unlock and withdraw --- contracts/dao/governance/Governor.sol | 4 +- .../dao/governance/TimelockController.sol | 2 +- .../dao/staking/packages/StakingHandler.sol | 7 +- .../dao/governance/proposal-flow.test.js | 14 ++-- scripts/tests/dao/staking/staking.test.js | 77 +++++++++++++++++++ 5 files changed, 90 insertions(+), 14 deletions(-) diff --git a/contracts/dao/governance/Governor.sol b/contracts/dao/governance/Governor.sol index ce9d5ca..c9d3dd5 100644 --- a/contracts/dao/governance/Governor.sol +++ b/contracts/dao/governance/Governor.sol @@ -454,10 +454,8 @@ abstract contract Governor is Context, ERC165, EIP712, IGovernor { bytes32 /*descriptionHash*/ ) internal virtual { for (uint256 i = 0; i < targets.length; ++i) { - string memory errorMessage = "Governor: call reverted without message"; (bool success, bytes memory returndata) = targets[i].call{ value: values[i] }(calldatas[i]); - //emit ExecuteTransaction(msg.sender, success, returndata); - Address.verifyCallResult(success, returndata, errorMessage); + emit ExecuteTransaction(msg.sender, success, returndata); } } diff --git a/contracts/dao/governance/TimelockController.sol b/contracts/dao/governance/TimelockController.sol index f44f55c..0a68c71 100644 --- a/contracts/dao/governance/TimelockController.sol +++ b/contracts/dao/governance/TimelockController.sol @@ -239,7 +239,7 @@ contract TimelockController is AccessControl, Initializable, ITimelockController bytes memory data ) internal virtual { (bool success, ) = target.call{ value: value }(data); - require(success, "TimelockController: underlying transaction reverted"); + emit ExecuteTransaction(msg.sender,success, data); } function _afterCall(bytes32 id) private { diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 3e6a2a2..e31f060 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -275,9 +275,10 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A revert NotPaused(); } uint256 numberOfLocks = locks[msg.sender].length; - for (uint256 lockId = 1; lockId <= numberOfLocks; lockId++) { - uint256 stakeValue = locks[msg.sender][lockId].amountOfToken; - _unlock(stakeValue, stakeValue, lockId, msg.sender); + uint256 lockIdToUnlockAlways = 1; + for (uint256 i = 0; i < numberOfLocks; i++) { + uint256 stakeValue = locks[msg.sender][0].amountOfToken; + _unlock(stakeValue, stakeValue, lockIdToUnlockAlways, msg.sender); } _withdraw(MAIN_STREAM); } diff --git a/scripts/tests/dao/governance/proposal-flow.test.js b/scripts/tests/dao/governance/proposal-flow.test.js index 0c56e43..1f5d51f 100644 --- a/scripts/tests/dao/governance/proposal-flow.test.js +++ b/scripts/tests/dao/governance/proposal-flow.test.js @@ -19,7 +19,7 @@ const AMOUNT_OUT_TREASURY = "1000"; // Events const PROPOSAL_CREATED_EVENT = "ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)" const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const EXECUTE_TRANSACTION_EVENT = "ExecuteTransaction(address,bool)"; +const EXECUTE_TRANSACTION_EVENT = "ExecuteTransaction(address,bool,bytes)"; const _encodeConfirmation = async (_proposalId) => { return web3.eth.abi.encodeFunctionCall({ @@ -810,8 +810,8 @@ describe('Proposal flow', () => { description_hash, {"from": accounts[0]} ); - // const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; - // expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) + const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; + expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) }); /// ------------- Relay Token -------/// it('Propose to add relay Token to other address', async() => { @@ -956,8 +956,8 @@ describe('Proposal flow', () => { } ); - // const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; - // expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) + const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; + expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) }); //relay ETH @@ -1107,8 +1107,8 @@ describe('Proposal flow', () => { } ); - // const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; - // expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) + const successStatus = eventsHelper.getIndexedEventArgs(result, EXECUTE_TRANSACTION_EVENT)[1]; + expect(successStatus.toString()).to.equal(TRUE_EVENT_RETURN_IN_HEX) }); it('Should blacklist a proposer', async() =>{ diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index 2cc584d..2c66a8b 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -1187,6 +1187,68 @@ describe("Staking Test", () => { await blockchain.mineBlock(await _getTimeStamp() + 100); }) + it('Should should make lock position staker_4', async() => { + const unlockTime = 1; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should should make lock position staker_4', async() => { + const unlockTime = 2; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should should make lock position staker_4', async() => { + const unlockTime = 3; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_4, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should should make lock position staker_3', async() => { + const unlockTime = 4; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_3, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should should make lock position staker_3', async() => { + const unlockTime = 0; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_3, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should should make lock position staker_3', async() => { + const unlockTime = 1; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_3, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should should make lock position staker_3', async() => { + const unlockTime = 2; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_3, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should should make lock position staker_3', async() => { + const unlockTime = 3; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_3, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should should make lock position staker_3', async() => { + const unlockTime = 4; + await blockchain.mineBlock(await _getTimeStamp() + 100); + let result3 = await stakingService.createLock(sumToDeposit,unlockTime,{from: staker_3, gas: maxGasForTxn}); + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) it('Paused contract should not make lock position', async() => { const toPauseFlag = 1 @@ -1221,6 +1283,21 @@ describe("Staking Test", () => { errorMessage ); }) + + + it('Should emergency Unlock and Withdraw', async() => { + await blockchain.mineBlock(await _getTimeStamp() + 100); + const result = await stakingService.emergencyUnlockAndWithdraw({"from": staker_4, gas: 30000000}); + console.log(result.gasUsed.toString()) + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) + + it('Should emergency Unlock and Withdraw', async() => { + await blockchain.mineBlock(await _getTimeStamp() + 100); + const result = await stakingService.emergencyUnlockAndWithdraw({"from": staker_3, gas: 30000000}); + console.log(result.gasUsed.toString()) + await blockchain.mineBlock(await _getTimeStamp() + 100); + }) it('Unpaused contract should make lock position', async() => { const toUnPauseFlag = 0 From 2f0e8517d7eae6cc1d72e8e60800eae5509b2b6c Mon Sep 17 00:00:00 2001 From: ssubik Date: Thu, 9 Feb 2023 20:38:54 +0545 Subject: [PATCH 65/77] adding tests --- scripts/tests/dao/staking/staking.test.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index 2c66a8b..12fcb24 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -1298,6 +1298,15 @@ describe("Staking Test", () => { console.log(result.gasUsed.toString()) await blockchain.mineBlock(await _getTimeStamp() + 100); }) + + it('Should have no locks', async() => { + const result1 = await stakingService.getAllLocks(staker_4) + const result2 = await stakingService.getAllLocks(staker_3) + console.log(result1) + console.log(result2) + assert.equal(result1.toString().length,0) + assert.equal(result2.toString().length,0) + }) it('Unpaused contract should make lock position', async() => { const toUnPauseFlag = 0 From e93c915976f40a890fbbe2ba3af761772cb847d7 Mon Sep 17 00:00:00 2001 From: ssubik Date: Fri, 10 Feb 2023 13:08:40 +0545 Subject: [PATCH 66/77] revisiting audits and emergency unlock and withdraw --- audit-report/Fathom_DAO-review.md | 35 +++++++++---------- .../dao/governance/MainTokenGovernor.sol | 2 ++ .../dao/staking/packages/StakingHandler.sol | 13 +++---- .../dao/staking/packages/StakingInternals.sol | 4 +-- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/audit-report/Fathom_DAO-review.md b/audit-report/Fathom_DAO-review.md index b99aef1..68a2dcf 100644 --- a/audit-report/Fathom_DAO-review.md +++ b/audit-report/Fathom_DAO-review.md @@ -101,7 +101,7 @@ The reaudited commit identifier with implemented Oxorio's recommendations is [`d ### CRITICAL -#### [NEW] There's no `owners` array length validation in the constructor of `MultiSigWallet`[DONE - VERIFIED] +#### [NEW] There's no `owners` array length validation in the constructor of `MultiSigWallet`[DONE - VERIFIED -CHECKED] ##### Description In the [MultiSigWallet\`s constructor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L76) there's no checking that the number of `owners` is less than or equal `MAX_OWNER_COUNT`. If the contract is created with `owners` with length more than `MAX_OWNER_COUNT` then that makes calls to `addOwner`, `changeRequirement` and `removeOwner` (which uses call `changeRequirement`) functions impossible because they use modifier `validRequirement` with this `require` statement: ```solidity @@ -143,7 +143,7 @@ Implemented Auditors Recommendation. with slight change: changeRequirement(numConfirmationsRequired + _owners.length); ``` -#### 1. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE -ASK Anton - ask auditor, does it require to revoke confirmation in executeTransaction, TODAY] +#### 1. [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[NOTDONE -ASK Anton - ask auditor, does it require to revoke confirmation in executeTransaction, TODAY - CHECKAGAIN] ##### Description In the function [`removeOwner`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L96) the owner is being removed without revocation of transaction signatures, where they've signed. This creates a situation where the signatures of non-existent owners may be used. For example, like in the following scenario: @@ -180,7 +180,7 @@ We recommend adding logic that would allow you to cancel the execution of `propo ###### Fathom's response Implemented Auditors Recommendation. -#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE - ASK AUDITOR-Verified] +#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE - ASK AUDITOR-Verified -CHECKED] ##### Description A change of the `timelock` parameter in the [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L22) contract can lead to already executed `proposals` being able to be executed again. This is connected to the fact that the execution status of the transaction is saved only in the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, and the `GovernorTimelockControl` contract makes calls to the `TimelockController` functions to get the `proposals` status in the [`state`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L50) function. ##### Recommendation @@ -256,7 +256,7 @@ modifier validRequirement(uint ownerCount, uint _required) { } ``` -#### [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet`[NOTDONE -ASK AUDITOR -Verified] +#### [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet`[NOTDONE -ASK AUDITOR -Verified -CHECKAGAIN] ##### Description In the structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) there's no lifetime parameter `expired`, which is responsible for the period of time during which the transaction must be executed. Since transactions may be executed at random time and are not removed over time, frozen, previously not approved transactions can be executed after a certain time and cause an undesirable effect. ##### Recommendation @@ -303,7 +303,7 @@ We recommend adding the `updateMultisig` function, but so that only the old `mul ###### Fathom's response Implemented Auditors Recommendation. -#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE -> ASK AUDITOR FOR HELP, TODAY ASK AUDITOR-Verified. AGAINVERIFY] +#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE -> ASK AUDITOR FOR HELP, TODAY ASK AUDITOR-Verified. AGAINVERIFY -CHECKED] ##### Description There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. ##### Recommendation @@ -346,7 +346,7 @@ We recommend adding a constant with the minimum allowable value of `_quorumNumer Implemented Auditors Recommendation. -#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE - Ask Auditor- VERIFIEd] +#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE - Ask Auditor- VERIFIEd -CHECKED] ##### Description In the [VMainToken](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) contract, for mint tokens, calling account, in addition to having `MINTER_ROLE` rights, must also be in the `isWhiteListed` list, since the mint function calls `_mint,` which contains [`_beforeTokenTransfer`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65) call. When `_beforeTokenTransfer` is called, it checks that the `msg.sender` address is in the `isWhiteListed` list. @@ -394,7 +394,7 @@ But it should be noted that `addToWhitelist` and `removeFromWhitelist` can be ca We recommend refactoring this code and adding internal functions `_addToWhitelist` and `_removeFromWhitelist` without access control to `grantMinterRole` and `revokeMinterRole`. -#### 3. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[DONE, Ask Auditor, Verified] +#### 3. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[DONE, Ask Auditor, Verified - CHECKED] ##### Description In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. ##### Recommendation @@ -419,7 +419,7 @@ We recommend making two different functions for relaying `ERC20` tokens and nati -#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor -> VERIFIED] +#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor -> VERIFIED - CHECKED] ##### Description The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol) contract lacks the ability to suspend a contract in an emergency and migrate assets to a new compatible `VaultPackage` contract. @@ -438,7 +438,7 @@ We recommend forbidding to use functions after migration. We recommend using `deposited` variable instead `balanceOf` `VaultPackage` balance. -#### 4. [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE-> Do at last Ask Auditor VERIFIED] +#### 4. [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE-> Do at last Ask Auditor VERIFIED - CHECKED] ##### Description In the `StakingHandlers` contract, calling the function [`updateVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L269) can cause all contract functions that work with balances and `VaultPackage` functions to be blocked. ##### Recommendation @@ -466,7 +466,6 @@ The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contrac Despite checking that the `vault` is migrated, there is no validation that `_vault` is a compatible `VaultPackage`, which is the contract where the migration took place. We recommend adding new statement that `_vault` is `VaultPackage` for migration. -[accept this, as Admin will be sure to do it correctly] #### [FIXED] There is no emergency suspension of the rewards payment in the `VaultPackage` contract ##### Description @@ -487,7 +486,7 @@ We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppeli ###### Fathom's response Implemented Auditors Recommendation. -#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE , VERIFIED] +#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE , VERIFIED - CHECKED] ##### Description In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. @@ -506,7 +505,7 @@ Recommendation has not been fully implemented. In the current version there is s We recommend adding a separate withdraw function, that would allow the `DEFAULT_ADMIN_ROLE` address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). -#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE - Ask Auditor -VERFIED] +#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE - Ask Auditor -VERFIED - CHECKED] ##### Description In the `StakingHandlers` contract the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function does not allocate tokens for rewards `MAIN_STREAM`, as it happens when [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) is called. This may result in the block of the `withdrawStream` function call from the `MAIN_STREAM` of tokens and rewards for some users, if the amount in `VaultPackage` is less than the amount stated in `scheduleRewards`. ##### Recommendation @@ -565,7 +564,7 @@ bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); ###### Fathom's response Implemented Auditors Recommendation. -#### 5. [NEW] Transaction should be marked as `executed` if the call fails[DONE Ask Auditor -NOTDONE, check again ---!!!!!! TODO] +#### 5. [NEW] Transaction should be marked as `executed` if the call fails[DONE Ask Auditor -NOTDONE, check again ---!!!!!! TODO - CHECKED But CHECKAGAIN] ##### Description @@ -624,7 +623,7 @@ We recommend: ###### Fathom's response Implemented Auditors Recommendation. -#### 14 .[NEW] `prohibitedEarlyWithdraw` is not set to `false` for `lockid` after unlocking in `StakingHandlers`[DONE -VERIFIED] +#### 14 .[NEW] `prohibitedEarlyWithdraw` is not set to `false` for `lockid` after unlocking in `StakingHandlers`[DONE -VERIFIED - CHECKeD] ##### Description In the function [`createLockWithoutEarlyWithdraw`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L181) in the `StakingHandlers` contract parameter `prohibitedEarlyWithdraw` for given `lockid` is set to `true`, but it does not update to `false` after unlocking later in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions. Since the value in the `locks` array is deleted after the unlock, all new values will be assigned the value of `prohibitedEarlyWithdraw`, regardless of whether the `createLockWithoutEarlyWithdraw` or `createLock` function is called. @@ -781,7 +780,7 @@ We recommend removing `Governance` from this modifier and give the permission to ###### Fathom's response Thats the way its designed -#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[DONE - Ask Auditor VERIFIED] +#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[DONE - Ask Auditor VERIFIED- CHECKED] ##### Description In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. Based on the logic of the contract, there may be the following cases: @@ -845,7 +844,7 @@ In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom- ##### Recommendation We recommend adding balance check while adding a transaction with a non-zero value `_value`. -#### [NEW] There is no time limit for executing proposal in `Governor`[Ask ANTON -DONE Ask VERFIED] +#### [NEW] There is no time limit for executing proposal in `Governor`[Ask ANTON -DONE Ask VERFIED - CHECKED] ##### Description The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract has no parameters for the time limit on `proposal` execution. This can result in no longer relevant proposal being executed after a period of time. ##### Recommendation @@ -881,7 +880,7 @@ require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Go ###### Fathom's response Implemented Auditors Recommendation. -#### 17. [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[DONE - ASK AUDITOR TODAY -VERIFIED] +#### 17. [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[DONE - ASK AUDITOR TODAY -VERIFIED - CHECKED] ##### Description In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) contracts the `execute` functions do not check the `msg.value` balance value needed to execute `_targets`, which would result in gas consumption even if the amount of `ETH` is not enough. ##### Recommendation @@ -983,7 +982,7 @@ We recommend adding a condition that `createStream` can only be called from the ###### Fathom's response Implemented Auditors Recommendation. -#### 8. [NEW] Possible overflow with calculations[NOTDONE]//TODO +#### 8. [NEW] Possible overflow with calculations[NOTDONE]//TODO [CHECKAGAIN] ##### Description In the next lines there is a possible overflow: diff --git a/contracts/dao/governance/MainTokenGovernor.sol b/contracts/dao/governance/MainTokenGovernor.sol index d1e5ad3..1b380c7 100644 --- a/contracts/dao/governance/MainTokenGovernor.sol +++ b/contracts/dao/governance/MainTokenGovernor.sol @@ -112,6 +112,8 @@ contract MainTokenGovernor is } function _removeSupportingToken(address _token) internal { + require(isSupportedToken[_token], "Token already doesnt exist"); + isSupportedToken[_token] = false; for (uint256 i = 0; i < listOfSupportedTokens.length; i++) { if (listOfSupportedTokens[i] == _token) { listOfSupportedTokens[i] = listOfSupportedTokens[listOfSupportedTokens.length - 1]; diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index e31f060..d4f58f0 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -211,8 +211,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A require(lock.end <= block.timestamp, "lock close"); _updateStreamRPS(); uint256 stakeValue = lock.amountOfToken; - _unlock(stakeValue, stakeValue, lockId, msg.sender); prohibitedEarlyWithdraw[msg.sender][lockId] = false; + _unlock(stakeValue, stakeValue, lockId, msg.sender); + } function unlockPartially(uint256 lockId, uint256 amount) public override pausable(1) { @@ -221,8 +222,8 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A require(lock.end <= block.timestamp, "lock close"); _updateStreamRPS(); uint256 stakeValue = lock.amountOfToken; - _unlock(stakeValue, amount, lockId, msg.sender); prohibitedEarlyWithdraw[msg.sender][lockId] = false; + _unlock(stakeValue, amount, lockId, msg.sender); } function earlyUnlock(uint256 lockId) public override pausable(1) { @@ -275,10 +276,9 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A revert NotPaused(); } uint256 numberOfLocks = locks[msg.sender].length; - uint256 lockIdToUnlockAlways = 1; - for (uint256 i = 0; i < numberOfLocks; i++) { - uint256 stakeValue = locks[msg.sender][0].amountOfToken; - _unlock(stakeValue, stakeValue, lockIdToUnlockAlways, msg.sender); + for (uint256 lockId = numberOfLocks; lockId >= 1; lockId--) { + uint256 stakeValue = locks[msg.sender][lockId - 1].amountOfToken; + _unlock(stakeValue, stakeValue, lockId, msg.sender); } _withdraw(MAIN_STREAM); } @@ -331,6 +331,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } LockedBalance storage lock = locks[msg.sender][lockId - 1]; require(lock.owner == msg.sender, "bad owner"); + } function _transfer(uint256 _amount, address _token) internal{ diff --git a/contracts/dao/staking/packages/StakingInternals.sol b/contracts/dao/staking/packages/StakingInternals.sol index 4c29cfc..f10b175 100644 --- a/contracts/dao/staking/packages/StakingInternals.sol +++ b/contracts/dao/staking/packages/StakingInternals.sol @@ -17,7 +17,7 @@ contract StakingInternals is RewardsInternals { // solhint-disable not-rely-on-time error ZeroAddress(); error ZeroLocked(uint256 lockId); - error ZeroTotalToken(); + error ZeroTotalStakedToken(); function _initializeStaking( address _mainToken, address _voteToken, @@ -99,7 +99,7 @@ contract StakingInternals is RewardsInternals { revert ZeroLocked(lockId); } if(totalAmountOfStakedToken == 0){ - revert ZeroTotalToken(); + revert ZeroTotalStakedToken(); } uint256 nVoteToken = updateLock.amountOfVoteToken; From 15308669b0c2aaf8956010051fa64d9ea5dd4b48 Mon Sep 17 00:00:00 2001 From: ssubik Date: Fri, 10 Feb 2023 14:30:48 +0545 Subject: [PATCH 67/77] owners.values() --- contracts/dao/treasury/MultiSigWallet.sol | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/contracts/dao/treasury/MultiSigWallet.sol b/contracts/dao/treasury/MultiSigWallet.sol index 9fd6ef5..4eb86b6 100644 --- a/contracts/dao/treasury/MultiSigWallet.sol +++ b/contracts/dao/treasury/MultiSigWallet.sol @@ -248,12 +248,7 @@ contract MultiSigWallet is IMultiSigWallet { } function getOwners() public view override returns (address[] memory) { - uint256 lengthOfOwners = owners.length(); - address[] memory returnOwners = new address[](lengthOfOwners); - for(uint256 i; i < lengthOfOwners;i++){ - returnOwners[i] = owners.at(i); - } - return returnOwners; + return owners.values(); } function getTransactionCount() public view override returns (uint256) { From 74495570888c58da3823a08ddfb02f79b3aa5dc6 Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 13 Feb 2023 18:30:05 +0545 Subject: [PATCH 68/77] create lock without early withdraw --- contracts/dao/staking/interfaces/IStakingHandler.sol | 1 + contracts/dao/staking/packages/StakingHandler.sol | 7 +++++++ coralX-config.js | 2 +- scripts/tests/dao/staking/staking.test.js | 2 +- 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/contracts/dao/staking/interfaces/IStakingHandler.sol b/contracts/dao/staking/interfaces/IStakingHandler.sol index 07e776e..c495ec5 100644 --- a/contracts/dao/staking/interfaces/IStakingHandler.sol +++ b/contracts/dao/staking/interfaces/IStakingHandler.sol @@ -65,4 +65,5 @@ interface IStakingHandler { function emergencyUnlockAndWithdraw() external; function createLocksForCouncils(CreateLockParams[] calldata lockParams) external; + function createLockWithoutEarlyWithdrawal(uint256 amount, uint256 lockPeriod) external; } diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index e15cc9f..2b53077 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -208,6 +208,11 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A _createLock(amount, lockPeriod, msg.sender); } + function createLockWithoutEarlyWithdrawal(uint256 amount, uint256 lockPeriod) public override pausable(1){ + prohibitedEarlyWithdraw[msg.sender][locks[msg.sender].length + 1] = true; + _createLock(amount, lockPeriod, msg.sender); + } + function unlock(uint256 lockId) public override pausable(1) { _verifyUnlock(lockId); LockedBalance storage lock = locks[msg.sender][lockId - 1]; @@ -352,4 +357,6 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } minLockPeriod = _minLockPeriod; } + + } diff --git a/coralX-config.js b/coralX-config.js index 2cee8e5..78091c0 100644 --- a/coralX-config.js +++ b/coralX-config.js @@ -36,7 +36,7 @@ module.exports = { optimizer: { enabled: true, details: { yul: false }, - runs: 200, + runs: 150, }, evmVersion: 'istanbul', }, diff --git a/scripts/tests/dao/staking/staking.test.js b/scripts/tests/dao/staking/staking.test.js index ca10085..6d40f3b 100644 --- a/scripts/tests/dao/staking/staking.test.js +++ b/scripts/tests/dao/staking/staking.test.js @@ -1136,7 +1136,7 @@ describe("Staking Test", () => { const lockingPeriod = 364 * 24 * 60 * 60 await blockchain.mineBlock(await _getTimeStamp() + 100); const sumToDeposit = web3.utils.toWei('200', 'ether'); - let result1 = await stakingService.createLock(sumToDeposit,lockingPeriod, {from: accounts[9], gas: maxGasForTxn}); + let result1 = await stakingService.createLock(sumToDeposit,lockingPeriod, {from: accounts[9]}); await blockchain.mineBlock(await _getTimeStamp() + 100); }) From adfbf153c645c29c5fc984915dbeb2eaf05ec35d Mon Sep 17 00:00:00 2001 From: ssubik Date: Mon, 13 Feb 2023 21:06:14 +0545 Subject: [PATCH 69/77] making deployment scripts ready --- .../dao/staking/packages/StakingHandler.sol | 3 +- scripts/helpers/upgrades.js | 46 ---- .../deployment/4_deploy_main_token.js | 2 +- .../deployment/5_deploy_governor.js | 15 +- scripts/migrations/prod/5_init_main_stream.js | 33 +-- .../migrations/prod/6_setup_council_stakes.js | 4 +- .../setup/1_init_timelock_controller.js | 6 +- .../create-pool-through-governance.js | 258 ------------------ .../units/transfer-tokens-one-signature.js | 49 ++++ .../units/transfer-tokens-three-signature.js | 0 10 files changed, 73 insertions(+), 343 deletions(-) delete mode 100644 scripts/helpers/upgrades.js delete mode 100644 scripts/stablecoin-integration/create-pool-through-governance.js create mode 100644 scripts/units/transfer-tokens-one-signature.js create mode 100644 scripts/units/transfer-tokens-three-signature.js diff --git a/contracts/dao/staking/packages/StakingHandler.sol b/contracts/dao/staking/packages/StakingHandler.sol index 2b53077..3bd1a15 100644 --- a/contracts/dao/staking/packages/StakingHandler.sol +++ b/contracts/dao/staking/packages/StakingHandler.sol @@ -267,6 +267,7 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A require(streams[streamId].status == StreamStatus.ACTIVE, "stream inactive"); _withdraw(streamId); } + function withdrawAllStreams() public override pausable(1) { User storage userAccount = users[msg.sender]; @@ -357,6 +358,4 @@ contract StakingHandlers is StakingStorage, IStakingHandler, StakingInternals, A } minLockPeriod = _minLockPeriod; } - - } diff --git a/scripts/helpers/upgrades.js b/scripts/helpers/upgrades.js deleted file mode 100644 index 37f3638..0000000 --- a/scripts/helpers/upgrades.js +++ /dev/null @@ -1,46 +0,0 @@ -const ProxyAdmin = artifacts.require('./common/proxy/transparent/ProxyAdmin.sol'); -const TransparentUpgradeableProxy = artifacts.require('./common/proxy/transparent/TransparentUpgradeableProxy.sol'); -const fs = require('fs'); - -const rawdata = fs.readFileSync('../../addresses.json'); -let proxyAddress = JSON.parse(rawdata); - -async function deployProxy( - deployer, - packageAddr, - toInitialize, - ProxyAdminName, - ProxyName -) -{ - await deployer.deploy(ProxyAdmin, {gas:8000000}); - - const deployedProxyAdmin = artifacts.require('./common/proxy/transparent/ProxyAdmin.sol'); - - await deployer.deploy(TransparentUpgradeableProxy, packageAddr, ProxyAdmin.address, toInitialize, {gas:8000000}) - const deployedProxy = artifacts.require('./common/proxy/transparent/TransparentUpgradeableProxy.sol'); - - let addressUpdate = { - [ProxyAdminName]: deployedProxyAdmin.address, - [ProxyName]: deployedProxy.address - } - const newAddresses = { - ...proxyAddress, - ...addressUpdate - } - - let data = JSON.stringify(newAddresses); - fs.writeFileSync('./addresses.json',data, function(err){ - if(err){ - console.log(err) - } - }) - - return [deployedProxyAdmin.address, deployedProxy.address] -} - -module.exports = { deployProxy }; - - - - diff --git a/scripts/migrations/deployment/4_deploy_main_token.js b/scripts/migrations/deployment/4_deploy_main_token.js index 44e9b2c..30f3318 100644 --- a/scripts/migrations/deployment/4_deploy_main_token.js +++ b/scripts/migrations/deployment/4_deploy_main_token.js @@ -4,7 +4,7 @@ const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); const mainToken = { name: "Fathom Protocol Token", symbol: "FTHM", - totalSupply: web3.utils.toWei("1000000000000000000000000000", "wei"), + totalSupply: web3.utils.toWei("1000000000", 'ether'), issuer: MultiSigWallet.address }; diff --git a/scripts/migrations/deployment/5_deploy_governor.js b/scripts/migrations/deployment/5_deploy_governor.js index 5de539d..2897056 100644 --- a/scripts/migrations/deployment/5_deploy_governor.js +++ b/scripts/migrations/deployment/5_deploy_governor.js @@ -6,11 +6,16 @@ const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const VMainToken_address = VMainToken.address; const TimelockController_address = TimelockController.address; const MultiSigWallet_address = MultiSigWallet.address; -const initialVotingDelay = 30; -const votingPeriod = 450; -const initialProposalThreshold = 1000; -const proposalTimeDelay = 5; -const proposalLifetime = 86400; +const initialVotingDelay = 86400; //Approx. 2 days with one block every 2s +const votingPeriod = 216000; // (5 * 24 * 60 * 60) / 2, approx. 5 days with one block every 2s +const initialProposalThreshold = 1000; +// time delay is in timestamp not block. +// Each user cannot make proposals if they have recently made a proposal, for a given time delay. +// This given delay is proposalTimeDelay, the time between multiple proposals for each user +const proposalTimeDelay = 86400; +// After the proposal is created, till what time period the proposal can be executed. +// After the lifetime exceeds, the proposal can’t be executed. +const proposalLifetime = 14 * 86400; module.exports = async function(deployer) { diff --git a/scripts/migrations/prod/5_init_main_stream.js b/scripts/migrations/prod/5_init_main_stream.js index b9c5e87..eb191d1 100644 --- a/scripts/migrations/prod/5_init_main_stream.js +++ b/scripts/migrations/prod/5_init_main_stream.js @@ -50,37 +50,18 @@ const _encodeInitMainStreamFunction = (_owner, _scheduleTimes, _scheduleRewards, return toInitializeMainStream } -const tau = 60; module.exports = async function(deployer) { - // const startTime = 1675526400 //EIGHT_PM_UAE_TIME_FEB_FOUR_Timestamp - const startTime = 1678328872 //TWELVE_PM_UAE_TIME_FEB_SEVEN_Timestamp - const oneDay = 86400; + const startTime = 1676577600 //ZERO_AM_UAE_TIME_SEVENTEEN_FEB_TIMESTAMP + const oneMonth = 2628288 const scheduleTimes = [ startTime, - startTime + 1 * oneDay, - startTime + 2 * oneDay, - startTime + 3 * oneDay, - startTime + 4 * oneDay, - startTime + 5 * oneDay, - startTime + 6 * oneDay, - startTime + 7 * oneDay, - startTime + 8 * oneDay, - startTime + 9 * oneDay, - startTime + 10 * oneDay + startTime + 36 * oneMonth ]; + const tau = 432000;//FIVE DAYS const scheduleRewards = [ - web3.utils.toWei('150000000', 'ether'), - web3.utils.toWei('135000000', 'ether'), - web3.utils.toWei('120000000', 'ether'), - web3.utils.toWei('105000000', 'ether'), - web3.utils.toWei('90000000', 'ether'), - web3.utils.toWei('75000000', 'ether'), - web3.utils.toWei('60000000', 'ether'), - web3.utils.toWei('45000000', 'ether'), - web3.utils.toWei('30000000', 'ether'), - web3.utils.toWei('15000000', 'ether'), + web3.utils.toWei('400000000', 'ether'), web3.utils.toWei('0', 'ether') ]; @@ -109,7 +90,5 @@ module.exports = async function(deployer) { let txIndexInit = eventsHelper.getIndexedEventArgs(resultInit, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexInit, {gas: 8000000}); - const resultOfInitMainStream = await multiSigWallet.executeTransaction(txIndexInit, {gas: 8000000}); - const successStatusInitMainStream = eventsHelper.getIndexedEventArgs(resultOfInitMainStream, ExecuteTransactionSuccess); - console.log(successStatusInitMainStream) + const resultOfInitMainStream = await multiSigWallet.executeTransaction(txIndexInit, {gas: 10000000}); } diff --git a/scripts/migrations/prod/6_setup_council_stakes.js b/scripts/migrations/prod/6_setup_council_stakes.js index e4d1e22..0f07fb4 100644 --- a/scripts/migrations/prod/6_setup_council_stakes.js +++ b/scripts/migrations/prod/6_setup_council_stakes.js @@ -13,8 +13,8 @@ const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint const LOCK_PERIOD = 4 * 24 * 60 * 60; -const T_TO_TRANSFER = web3.utils.toWei('150000000', 'ether'); -const T_TO_STAKE = web3.utils.toWei('50000000', 'ether'); +const T_TO_TRANSFER = web3.utils.toWei('30000000', 'ether'); +const T_TO_STAKE = web3.utils.toWei('10000000', 'ether'); const COUNCIL_1 = "0xc0Ee98ac1a44B56fbe2669A3B3C006DEB6fDd0f9"; const COUNCIL_2 = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; diff --git a/scripts/migrations/setup/1_init_timelock_controller.js b/scripts/migrations/setup/1_init_timelock_controller.js index 79887c4..61ec73a 100644 --- a/scripts/migrations/setup/1_init_timelock_controller.js +++ b/scripts/migrations/setup/1_init_timelock_controller.js @@ -5,8 +5,10 @@ const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); // interfaces const ITimelockController = artifacts.require('./dao/governance/interfaces/ITimelockController.sol'); - -const minDelay = 30; +// A Scheduled operation is an operation that becomes valid after a given delay. +// Once the delay time has passed, the operation can be performed. Each schedules delay must be at least minDelay. +// minDelay is set in the initialize function call, and can be updated using function updateDelay. +const minDelay = 30; //?? What should be initialized? const proposers = [MainTokenGovernor.address]; const executors = [MainTokenGovernor.address]; diff --git a/scripts/stablecoin-integration/create-pool-through-governance.js b/scripts/stablecoin-integration/create-pool-through-governance.js deleted file mode 100644 index 8d7cac8..0000000 --- a/scripts/stablecoin-integration/create-pool-through-governance.js +++ /dev/null @@ -1,258 +0,0 @@ -const blockchain = require("../tests/helpers/blockchain"); -const eventsHelper = require("../tests/helpers/eventsHelper"); -const { assert } = require("chai"); -// const BigNumber = require("bignumber.js"); - -const { BigNumber } = require("ethers"); -const { formatBytes32String } = require("ethers/lib/utils"); - -// Proposal 1 -const PROPOSAL_DESCRIPTION = "Proposal #3: Init stablecoin collateral pool"; -const NEW_STORE_VALUE = "5"; - -// Events -const PROPOSAL_CREATED_EVENT = "ProposalCreated(uint256,address,address[],uint256[],string[],bytes[],uint256,uint256,string)" -const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; - -// Token variables -const T_TOKEN_TO_TRANSFER = "100000000000000000000000"; -const T_TO_STAKE = web3.utils.toWei('2000', 'ether'); -const STAKED_MIN = web3.utils.toWei('1900', 'ether'); - -const SYSTEM_ACC = accounts[0]; -const stream_owner = accounts[3]; -const STAKER_1 = accounts[5]; -const STAKER_2 = accounts[6]; -const NOT_STAKER = accounts[7]; - -const _getTimeStamp = async () => { - const timestamp = await blockchain.getLatestBlockTimestamp() - return timestamp -} - -// Collateral pool setup -const colPoolConfigAddress = "0x26B38db6A03E8c46611a9E4Cf61B2FeC5494FaFf"; - -//this is used for stream shares calculation. -const vMainTokenCoefficient = 500; - -let mainTokenGovernor; -let box; -let proposalId; -let result; -let encoded_function; -let description_hash; - -// initCollateralPool parameters - -// Need to fetch this from latest deployment from -const rawdata = '{"accessControlConfig":"0xa3B5e3c691C83b8440A38B80B451099c0da63574","collateralPoolConfig":"0x26B38db6A03E8c46611a9E4Cf61B2FeC5494FaFf","bookKeeper":"0x49Abc711f65d7E139B10D43F503BC9CDf829e5f0","fathomStablecoin":"0xfF1aD272c80444511444eAeD3AB1C4589AaDf86F","systemDebtEngine":"0x1d7571a073e0eB76222A38A643d192fA62EeB501","liquidationEngine":"0xE8ad10b5D603A696A77013aa1B9620D8De95d5f7","stablecoinAdapter":"0xCe77cb08d3f0C7C44d67e65966dB3a66d08cdcb9","priceOracle":"0x56DA731F3B4D5496109a5724aF20A5fa1e161Dd1","showStopper":"0x74DD97d7313947205Ac33e2C16172603BD9e91F5","fathomToken":"0x0ebE93530C27aD39516834AcCEf1be62c9f557E2","fairLaunch":"0x67a42C587d5b2aE6e91784EB91e4bB9428ffB8AA","WXDC":"0xAAcb1c4A83056d99357f9e93Ef50FB3cd05d6a2d","USDT":"0x9Ed0Ff4f44A233f6abBD6b2187c8fc34A2d74fC7","DNM":"0xeA8aA20dB7ce3Dd0D8C318207f1D96102d45A8c1","shield":"0x1cA13cF1aB59944A329599f17593297aA372f15b","positionManager":"0x801eEB237a2364A38f2c9B82C0CD54cc5Bf5abA8","collateralTokenAdapter":"0x136e516984dC410F76EA32F8a18245191F683D60","simplePriceFeed":"0x149155B9cAd53847CC7cdEB4D6FED88ff6f31761","simplePriceFeedUSDT":"0xd72E7b17435520d7CcBf5336e0BaEf5E94b317DB","simplePriceFeedUSDTCOL":"0xE33d3fffe00F78BA3bEf3BDB39aBAAB7CAD1FbD2","simplePriceFeedFTHM":"0xCBD10516685B0d91914543DBb189e4dDd864cDAb","fixedSpreadLiquidationStrategy":"0x17d186B5B7724cE901cC6792D23626ED6530b760","fathomStablecoinProxyActions":"0xaA70aD720f130e57d4bD80517e57A441f5F21E12","stabilityFeeCollector":"0x739e916d40864d6eB09F1943A510Cb2657E223fb","proxyWalletFactory":"0x86504933bb9d24Ea2fECA6679836BBC07570b08D","proxyWalletRegistry":"0x335bEBc68b1d249E0Db8E20990255b2Ff985CdDf","authTokenAdapter":"0x046883899EBE0A9f6a8FA3982ca5C421B39CF9EE","stableSwapModule":"0x931aC07e0f9CA2c477DB45Eb870D7EF7e823ee82","getPositions":"0xD3974Fd03F98cABcCE0a120FD02599C736480650","collateralTokenAdapterUSDT":"0xe45C2c97d9FB27d89B8f9d7BF9568E4CBC73a151","collateralTokenAdapterFTHM":"0xbf7599eA133BC24f84897599364801e344bB7E81","collateralTokenAdapterUSDTCOL":"0xdD057bf9B343b41E3ABd625959E63c8Ccc23C679","collateralTokenAdapterDNM":"0xEeA2a5Fc00F128E4F46db2dCB4183f4638D9e93E"}' -let stablecoinAddress = JSON.parse(rawdata); - - -// const WeiPerWad = BigNumber.from(`1${"0".repeat(18)}`) -// const WeiPerRay = BigNumber.from(`1${"0".repeat(27)}`) -// const WeiPerRad = BigNumber.from(`1${"0".repeat(45)}`) - -const WeiPerWad = `1${"0".repeat(18)}` -const WeiPerRay = `1${"0".repeat(27)}` -const WeiPerRad = `1${"0".repeat(45)}` -const COLLATERAL_POOL_ID = formatBytes32String("DNM"); -const CLOSE_FACTOR_BPS = 5000 -const LIQUIDATOR_INCENTIVE_BPS = 10500 -const TREASURY_FEE_BPS = 5000 - -params = [ - COLLATERAL_POOL_ID, - 0, - 0, - stablecoinAddress.simplePriceFeedUSDT, - WeiPerRay, - WeiPerRay, - stablecoinAddress.collateralTokenAdapterDNM, - CLOSE_FACTOR_BPS*2, - LIQUIDATOR_INCENTIVE_BPS, - TREASURY_FEE_BPS, - stablecoinAddress.fixedSpreadLiquidationStrategy -] - -encoded_function = web3.eth.abi.encodeFunctionCall({ - name: 'initCollateralPool', - type: 'function', - inputs: [{ - type: 'bytes32', - name: '_collateralPoolId' - },{ - type: 'uint256', - name: '_debtCeiling' - },{ - type: 'uint256', - name: '_debtFloor' - },{ - type: 'address', - name: '_priceFeed' - },{ - type: 'uint256', - name: '_liquidationRatio' - },{ - type: 'uint256', - name: '_stabilityFeeRate' - },{ - type: 'address', - name: '_adapter' - },{ - type: 'uint256', - name: '_closeFactorBps' - },{ - type: 'uint256', - name: '_liquidatorIncentiveBps' - },{ - type: 'uint256', - name: '_treasuryFeesBps' - },{ - type: 'address', - name: '_strategy' - }] - }, params -); - - - -const CollateralPoolConfig = artifacts.require('./8.17/stablecoin-core/config/CollateralPoolConfig.sol'); - -module.exports = async function(deployer) { - - - const mainTokenGovernor = await CollateralPoolConfig.at(stablecoinAddress.collateralPoolConfig); - - // create a proposal in MainToken governor - result = await mainTokenGovernor.propose( - [stablecoinAddress.collateralTokenAdapter], - [0], - [encoded_function], - PROPOSAL_DESCRIPTION, - {"from": STAKER_1} - ); - // retrieve the proposal id - proposalId = eventsHelper.getIndexedEventArgs(result, PROPOSAL_CREATED_EVENT)[0]; -// }); - -// it('Check that the proposal status is: Pending', async() => { -// expect((await mainTokenGovernor.state(proposalId)).toString()).to.equal("0"); -// }) - -// it('Wait two blocks and then check that the proposal status is: Active', async() => { - - let currentNumber = await web3.eth.getBlockNumber(); - let block = await web3.eth.getBlock(currentNumber); - let timestamp = block.timestamp; - - var nextBlock = 1; - while (nextBlock <= 30) { - await blockchain.mineBlock(timestamp + nextBlock); - nextBlock++; - } - // Check that the proposal is open for voting - // expect((await mainTokenGovernor.state(proposalId)).toString()).to.equal("1"); -// }); - -// it('Vote on the proposal', async() => { - - // enum VoteType { - // Against, - // For, - // Abstain - // } - // => 0 = Against, 1 = For, 2 = Abstain - - currentNumber = await web3.eth.getBlockNumber(); - block = await web3.eth.getBlock(currentNumber); - timestamp = block.timestamp; - - nextBlock = 1; - while (nextBlock <= 30) { - await blockchain.mineBlock(timestamp + nextBlock); - nextBlock++; - } - // Vote: - await mainTokenGovernor.castVote(proposalId, "1", {"from": STAKER_1}); -// }); - - -// it('Wait 40 blocks and then check that the proposal status is: Succeeded', async() => { - currentNumber = await web3.eth.getBlockNumber(); - block = await web3.eth.getBlock(currentNumber); - timestamp = block.timestamp; - - nextBlock = 1; - while (nextBlock <= 450) { - await blockchain.mineBlock(timestamp + nextBlock); - nextBlock++; - } - - // expect((await mainTokenGovernor.state(proposalId)).toString()).to.equal("4"); -// }); - -// it('Queue the proposal', async() => { - - // Functions mainTokenGovernor.propose and mainTokenGovernor.queue have the same input, except for the - // description parameter, which we need to hash. - // - // A proposal can only be executed if the proposalId is the same as the one stored - // in the governer contract that has passed a vote. - // In the Governor.sol contract, the proposalId is created using all information used - // in to create the proposal: - // uint256 proposalId = hashProposal(targets, values, calldatas, keccak256(bytes(description))); - - result = await mainTokenGovernor.queue( - [stablecoinAddress.collateralTokenAdapter], - [0], - [encoded_function], - description_hash, - {"from": accounts[0]} - ); -// }); - -// it('Approve the proposal from accounts 0 AND 1', async() => { - - await mainTokenGovernor.confirmProposal(proposalId, {"from": accounts[0]}); - await mainTokenGovernor.confirmProposal(proposalId, {"from": accounts[1]}); -// }); - -// it('Wait 40 blocks and then check that the proposal status is: Queued', async() => { - - currentNumber = await web3.eth.getBlockNumber(); - block = await web3.eth.getBlock(currentNumber); - timestamp = block.timestamp; - - nextBlock = 1; - while (nextBlock <= 450) { - await blockchain.mineBlock(timestamp + nextBlock); - nextBlock++; - } - // expect((await mainTokenGovernor.state(proposalId)).toString()).to.equal("5"); -// }); - -// it('Execute the proposal', async() => { - - result = await mainTokenGovernor.execute( - [stablecoinAddress.collateralTokenAdapter], - [0], - [encoded_function], - description_hash, - {"from": accounts[0]} - ); - - console.log(result); - -}; - - -// it('Should retrieve the updated value proposed by governance for the new store value in box.sol', async() => { - -// const new_val = await box.retrieve(); - -// // Test if the returned value is the new value -// expect((await box.retrieve()).toString()).to.equal(NEW_STORE_VALUE); -// }); - diff --git a/scripts/units/transfer-tokens-one-signature.js b/scripts/units/transfer-tokens-one-signature.js new file mode 100644 index 0000000..ca5fae5 --- /dev/null +++ b/scripts/units/transfer-tokens-one-signature.js @@ -0,0 +1,49 @@ +const eventsHelper = require("../../tests/helpers/eventsHelper"); + +const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); + +const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; +const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; + +const T_TO_TRANSFER_PLACEHOLDER = web3.utils.toWei('','ether') //SET AS NEEDED +const TRANSFER_TO_ACCOUNT_PLACEHOLDER = "" //SET AS NEEDED +const MULTISIG_WALLET_ADDRESS = "" //CONSTANT +const MAIN_TOKEN_ADDRESS = "" //CONSTANT + +const _encodeTransferFunction = (_account, t_to_stake) => { + + let toRet = web3.eth.abi.encodeFunctionCall({ + name: 'transfer', + type: 'function', + inputs: [{ + type: 'address', + name: 'to' + },{ + type: 'uint256', + name: 'amount' + }] + }, [_account, t_to_stake]); + + return toRet; +} + + + +module.exports = async function(deployer) { + const multiSigWallet = await IMultiSigWallet.at(MULTISIG_WALLET_ADDRESS) + + const _transferFromMultiSigTreasury = async (_account, _value) => { + const result = await multiSigWallet.submitTransaction( + MAIN_TOKEN_ADDRESS, + EMPTY_BYTES, + _encodeTransferFunction(_account, _value), + 0, + {gas: 8000000} + ); + txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); + await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); + } + + await _transferFromMultiSigTreasury(TRANSFER_TO_ACCOUNT_PLACEHOLDER,T_TO_TRANSFER); +} \ No newline at end of file diff --git a/scripts/units/transfer-tokens-three-signature.js b/scripts/units/transfer-tokens-three-signature.js new file mode 100644 index 0000000..e69de29 From d9d28efa156551fc12d6745684ac7735585cecda Mon Sep 17 00:00:00 2001 From: ssubik Date: Tue, 14 Feb 2023 15:20:40 +0545 Subject: [PATCH 70/77] added unit scripts and made neater --- apothem-addresses-1.json | 1 - audit-report/Fathom DAO.pdf | Bin 1265693 -> 0 bytes audit-report/Fathom_DAO-review.md | 1566 ----------------- audit-report/Fathom_DAO.md | 1048 ----------- coralX-scenarios.js | 14 +- deprecated/scripts/2_init_staking.js | 125 -- .../prod/1_deploy_init_staking_proxy.js | 2 +- scripts/migrations/prod/5_init_main_stream.js | 3 +- .../migrations/prod/6_setup_council_stakes.js | 2 +- ...helpers.js => 7_staking_getter_helpers.js} | 0 .../save-address/1_save_address_deployment.js | 2 +- .../save-address/2_save_address_setup.js | 4 +- .../save-address/3_save_address_prod.js | 4 +- .../setup/1_init_timelock_controller.js | 2 +- .../setup-multisig-owners.js} | 21 +- .../units/transfer-tokens-three-signature.js | 0 ...ns-one-signature.js => transfer-tokens.js} | 19 +- 17 files changed, 45 insertions(+), 2768 deletions(-) delete mode 100644 apothem-addresses-1.json delete mode 100644 audit-report/Fathom DAO.pdf delete mode 100644 audit-report/Fathom_DAO-review.md delete mode 100644 audit-report/Fathom_DAO.md delete mode 100644 deprecated/scripts/2_init_staking.js rename scripts/migrations/prod/{8_staking_getter_helpers.js => 7_staking_getter_helpers.js} (100%) rename scripts/{migrations/prod/7_setup_multisig.js => units/setup-multisig-owners.js} (61%) delete mode 100644 scripts/units/transfer-tokens-three-signature.js rename scripts/units/{transfer-tokens-one-signature.js => transfer-tokens.js} (70%) diff --git a/apothem-addresses-1.json b/apothem-addresses-1.json deleted file mode 100644 index 79f52cc..0000000 --- a/apothem-addresses-1.json +++ /dev/null @@ -1 +0,0 @@ -{"vFTHM":"0x1Ba6e3Ac710bf5D0ecD55A927896255934c815Ce","timelockController":"0x5791391a4F14055AB74D721Db7B17c806c65c867","multiSigWallet":"0x37016c0eD7F4b92FA9f538093105f68438819Aec","fthmToken":"0xF8753B8A3629FCD73F039ea8743B6fCD7ce76a3a","fthmGovernor":"0x4Daa5ca5C21214042980c594E77b4C8767E3E84F","stakingImplementation":"0xbB0cB634c5296e4C1B52752ce900c44a5Afb1aa4","vaultImplementation":"0x66278fB561430f4C093142f0CA88f05714Fe7479","rewardsCalculator":"0x1Ce009729a30396d657D525258f445889b4491Ab","stakingProxyAdmin":"0x46f4f4198952299BC9703dCb2D7241F47F2D4950","staking":"0x5F083352ba467fB16a2913aD90DA20F6faD02E0C","vaultProxyAdmin":"0x1db13749E281540E9D66A6C9508FA6D0cDC29CE2","vault":"0x48654bB7E4166F1B6D0425d53C2E2DeC22973910","stakingGetter":"0xdFd0475B6999fBddD0De0d5386aA854236710091"} \ No newline at end of file diff --git a/audit-report/Fathom DAO.pdf b/audit-report/Fathom DAO.pdf deleted file mode 100644 index 0362f66bc04a16c06482898e1ef8ef2bd749eb85..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1265693 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

n07n9ou)NnW-V!X55@f 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

qmhbebrpo=` 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%0Aaw$S=^Fis5T^9~4~D+&RH;CavO!sYpY-QI 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

WY41-#Zxi*`fI(DT8!nP0S$$L7fA3 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 lastDisabledTransactionIndex, "MultiSig: old txs has been disabled"); - _; -} -``` - -This allows to manipulate with transaction acceptance, for example, it is possible to execute a transaction that removes a user before executing a transaction that collects confirmations. Thus, the transaction that has collected confirmations will be disabled and will not be able to be executed. -We propose refactoring this code according to the recommendation. - -#### [FIXED] There is no function that implements the `_cancel` proposal in `MainTokenGovernor` -##### Description -The contract [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) lacks a function that would implement the internal function [`_cancel`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L91), that allows you to cancel the execution of `proposal` with `TimelockController`. This can make it impossible to cancel the execution of a potentially dangerous call. -##### Recommendation -We recommend adding logic that would allow you to cancel the execution of `proposal` and call the internal function `_cancel`. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE - ASK AUDITOR-Verified -CHECKED] -##### Description -A change of the `timelock` parameter in the [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L22) contract can lead to already executed `proposals` being able to be executed again. This is connected to the fact that the execution status of the transaction is saved only in the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, and the `GovernorTimelockControl` contract makes calls to the `TimelockController` functions to get the `proposals` status in the [`state`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L50) function. -##### Recommendation -We recommend adding a separate mapping to the `GovernorTimelockControl` contract that would save information about the status of `proposal` and functions that would allow to update that status. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -Added: -```solidity -mapping(uint256 => bool) private isProposalExecuted; -``` -###### Oxorio's response -The recommendation has not been fully implemented. - -We recommend changing the work with the [`state`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L61) function to: -`isProposalExecuted[proposalId] == true` - - -#### [FIXED] The `initVault` and `initAdminAndOperator` functions can be initialized from any address in the `VaultPackage` contract -##### Description -In the `VaultPackage` contract the [`initVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L18) and [`initAdminAndOperator`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L26) functions can be called from any address. This could result in a potential attacker being able to intercept control for both `initVault` and `initAdminAndOperator` calls. -##### Recommendation -We suggest two solutions to this problem: - -- Combine the `initVault` and `initAdminAndOperator` functions into one `initialize` function and pass `calldata` to the [VaultProxy](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/proxy/VaultProxy.sol#L7) constructor in the `_data` parameter. -- Make a call to the `initVault` function on behalf of the `DEFAULT_ADMIN_ROLE`, and pass the `initVault` parameters just as `calldata` in the [VaultProxy](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/proxy/VaultProxy.sol#L7) constructor. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] There is no check that `stream` is active in the `StakingHandler` contract -##### Description -In the `StakingHandler` contract the [`withdrawAllStreams`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L243) and [`withdrawStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L236) functions do not have a check that `stream` is active. In the case of `withdrawAllStreams` this causes the function to use the entire `streams` array each time with active and inactive `streams` and, if there are not enough tokens on `VaultPackage`, the entire transaction will be `reverted`. In the case of `withdrawStream`, this can lead to `reverted` transaction, or unauthorized withdrawal of tokens from `VaultPackage`. - -##### Recommendation -We recommend adding to the `withdrawAllStreams` and `withdrawStream` functions a check that the output from `stream` has the status `ACTIVE`. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] Calling the `updateConfig` function may block the work of the `StakingHandlers` contract -##### Description -Calling the function [`updateConfig`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L252) in the `StakingHandler` contract can disrupt its work. This is possible for the following reasons: - -- There is no validation of `_weight` values. `_weight` can be equal to `0` and break the calculation of `share` in `streams` for staking holders. This will result in incorrect calculation of the repayment of staked tokens and rewards when exiting the stacking, which will block the work of the contract. -- Updating the `voteToken` parameter will cause the contract to try to burn new `voteToken` tokens that are not on the balance when [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) is called. -- Updating the parameters `rewardsCalculator`, `voteShareCoef`, `maxLockPeriod`, `maxLockPositions` will also lead to incorrect calculations and contract blocking. - -##### Recommendation -We recommend discarding the `updateConfig` function and consider mechanisms for stacking migration to a new contract with a suspension of the contract work during migration, e.g. `emergencyExit`. -##### Update -###### Fathom's response -Implemented `emergencyUnlockAndWithdraw` applicable when contract is paused. - -### MAJOR - -#### [FIXED] In `MultiSigWallet` there's no parameter defining minimum amount of signatures -##### Description -The parameter [`_numConfirmationsRequired`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L77) is checked in the constructor and in the function [`changeRequirement`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L116), that is not equal to `0`, however, when multi-signature is set, it allows the value `1`, and the contract may be used by one of the `owners`. - -##### Recommendation -We recommend adding minimum quantity constant for necessary signatures, e.g. `MIN_CONFIRMATIONS` and check if the set value is greater than or equal to `MIN_CONFIRMATIONS`. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -```solidity -modifier validRequirement(uint ownerCount, uint _required) { - require( - ownerCount > 0 && ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && ownerCount > 1 ? _required > 1 : _required > 0, - "MultiSig: Invalid requirement" - ); - _; -} -``` - -#### [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet`[NOTDONE -ASK AUDITOR -Verified -CHECKAGAIN] -##### Description -In the structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) there's no lifetime parameter `expired`, which is responsible for the period of time during which the transaction must be executed. Since transactions may be executed at random time and are not removed over time, frozen, previously not approved transactions can be executed after a certain time and cause an undesirable effect. -##### Recommendation -We recommend adding an individual parameter, which is responsible for the maximum time until the transaction can be executed, e.g. `expired` and check it before running transactions. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/treasury/MultiSigWallet.sol#L176) is not implemented correctly. -We meant the `lifetime` parameter, which is passed as a function parameter. - -`lifetime` must be greater than the minimum value and already be in the body of the function to get the value. - -`transactions[_txIndex].expireTimestamp = block.timestamp + lifetime` - -#### 5. [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[DONE -ASK AUDITOR - VERIFIED] -##### Description -In the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, Governance can take away the `TIMELOCK_ADMIN_ROLE` rights from the address `admin`. In the case of an attack on `Governance` and `Council` this would make it impossible to revoke the role from the captured contracts. -##### Recommendation -We recommend to consider a permissions policy or add the `DEFAULT_ADMIN_ROLE` for `admin` to be able to revoke the role in case of an attack. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/governance/TimelockController.sol#L57) was not fully implemented. -Admin role was added but not functions like `grantRole` and `revokeRole` for specific roles from the list of possible ones on behalf of `DEFAULT_ADMIN_ROLE`. -Only `TIMELOCK_ADMIN_ROLE` can change or delete `TIMELOCK_ADMIN_ROLE`, if the role was deleted from admin, then even having the `DEFAULT_ADMIN_ROLE` role, will not work with the built-in external functions of the `AccessControl` contract. - - -#### [FIXED] There is no validation for `maxTargets` when executing in `Governor` -##### Description -In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L142) function there is no validation of the maximum number of `targets`. This can cause `proposal` to have so many calls to external contracts that the execution transaction will face a "gas bomb" effect. This means a large amount of gas consumption or restricted gas limit block. -##### Recommendation -We recommend including the `maxTargets` parameter for `_targets`, the maximum number of `_targets` in the `proposal`. -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] There is no possibility to update `multisig` in `Governor` -##### Description -In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L34) contract there is no possibility to perform a migration to a new `multisig`. For example to a new version of the contract. -##### Recommendation -We recommend adding the `updateMultisig` function, but so that only the old `multisig` could call it. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### 6. [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE -> ASK AUDITOR FOR HELP, TODAY ASK AUDITOR-Verified. AGAINVERIFY -CHECKED] -##### Description -There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. -##### Recommendation -We recommend adding the `emergencyExit` function to the contract, which can be called by Governance by majority vote without confirmation with `multisig`. The function can be called once, its call stops the work of the contract. After calling this function, recovery is only possible by migrating to a new contract. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. and added `emergencyStop` -###### Oxorio's response -An `emergencyStop` method has been added, but the problem still remains. - -- The method just calls the `pause()` function -- The method is called on behalf of `Multisig`, which can be compromised. - -The main idea of this function is to put the contract into an emergency exit state, which can only be restored by completely replacing the contract and the states. This is an extreme case, an emergency stop. There should be no possibility to `unpause` after `emergencyStop` call. -We propose refactoring this code according to the recommendation. - -#### [FIXED] It is possible to set a null address in `GovernorTimelockControl` when updating `timelock`. -##### Description -In the `GovernorTimelockControl` contract it is possible to set a null address when calling the function [`_updateTimelock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L111). This can make the execution of `proposals` not possible since it is done through `timelock`. It will be also not possible to recover or change `timelock`, since it needs the corresponding proposal to be executed, which is also not possible with a zero `timelock`. -##### Recommendation -We recommend adding a check that the address `newTimelock != address(0)` -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -A redundant validation in the constructor in `GovernorTimelockControl`: -```solidity -require(address(timelockAddress) != address(0), "timelockAddress cant be zero address"); -``` -We recommend removing it because the same validation can be found in `_updateTimelock`. - - -#### [FIXED] There is no validation for null values for `newQuorumNumerator` in `GovernorVotesQuorumFraction` -##### Description -In the `GovernorVotesQuorumFraction` contract in the [`_updateQuorumNumerator`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol#L55) function it is possible to set `_quorumNumerator` to `0` value, which would lead to a complete voting stop. -##### Recommendation -We recommend adding a constant with the minimum allowable value of `_quorumNumerator` and perform a corresponding check in the `_updateQuorumNumerator` function. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - - -#### 7. [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE - Ask Auditor- VERIFIEd -CHECKED] -##### Description -In the [VMainToken](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) contract, for mint tokens, calling account, in addition to having `MINTER_ROLE` rights, must also be in the `isWhiteListed` list, since the mint function calls `_mint,` which contains [`_beforeTokenTransfer`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65) call. -When `_beforeTokenTransfer` is called, it checks that the `msg.sender` address is in the `isWhiteListed` list. -In the case of `mint`, it is the address with the `MINTER_ROLE` rights. -The administrator can grant/revoke `MINTER_ROLE` from an address by calling `grantRole`/`revokeRole`, but the `isWhitelisted` list remains unchanged - the old address stays in the list while the new one is never added. -This creates a risk that if `MINTER_ROLE` is compromised by an attacker, the admin will not be able to correctly revoke his rights, and the attacker can make a `transfer` of tokens to unauthorized addresses. -##### Recommendation -We recommend adding separate functions to grant and revoke the `MINTER_ROLE`, which will also add and remove addresses from the `isWhitelisted` list. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -- When revoking minter rights, `_grantRole` is used instead of `_revokeRole`. It should be changed to: -```solidity -function revokeMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)) { - _revokeRole(MINTER_ROLE, _minter); -``` - -- To add and remove from whitelist the following functions are used: - -```solidity - function addToWhitelist(address _toAdd) public override onlyRole(WHITELISTER_ROLE) { - isWhiteListed[_toAdd] = true; - emit MemberAddedToWhitelist(_toAdd); - } - - function removeFromWhitelist(address _toRemove) public override onlyRole(WHITELISTER_ROLE) { - isWhiteListed[_toRemove] = false; - emit MemberRemovedFromWhitelist(_toRemove); - } - function grantMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)){ - _grantRole(MINTER_ROLE, _minter); - - addToWhitelist(_minter); - } - - function revokeMinterRole(address _minter) public override onlyRole(getRoleAdmin(MINTER_ROLE)){ - _grantRole(MINTER_ROLE, _minter); - - removeFromWhitelist(_minter); - } -``` - -But it should be noted that `addToWhitelist` and `removeFromWhitelist` can be called from `WHITELISTER_ROLE`. In this case, `MINTER_ROLE` must also have `WHITELISTER_ROLE`. - -We recommend refactoring this code and adding internal functions `_addToWhitelist` and `_removeFromWhitelist` without access control to `grantMinterRole` and `revokeMinterRole`. - -#### 3. [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[DONE, Ask Auditor, Verified - CHECKED] -##### Description -In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. -##### Recommendation -We recommend fixing the possibility of withdrawal of tokens of the `ERC20` standard from the balance of Governance. This can be done in the following way: - -- It is a must to implement the `addSupportingTokens` function due to the fact that various tokens of the `ERC20` standard can be transferred to the Governance balance. Governance must work only with trusted tokens like USDT, USDC, etc. This function will make it possible to create a list of trusted tokens. Adding a token should only be done through Governance. -- Add a check to the `execute` function to confirm that `_target` is the contract address from the trusted tokens. And only in this case pass it to the `TimelockController` address. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -The [`relay`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/governance/MainTokenGovernor.sol#L100) function is implemented incorrectly. -```solidity - function relay(address target, uint256 value, bytes calldata data) external payable virtual onlyGovernance { - require(isSupportedToken[target],"relay: token not supported"); - (bool success, bytes memory returndata) = target.call{value: value}(data); - Address.verifyCallResult(success, returndata, "Governor: relay reverted without message"); - } -``` -Now it is possible to send value to a supported token contract. In this case all value sent to the token contract will be lost. -We recommend making two different functions for relaying `ERC20` tokens and native coins, e.g. `relayERC20` and `relayETH`. - - - -<<<<<<< HEAD -<<<<<<< HEAD -#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor -> Do we need to have not migrated check in withdraw Extra supported tokens Verified?] -======= -#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor -> VERIFIED] ->>>>>>> reaudit-fixes-final -======= -#### . [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE, Ask Auditor -> VERIFIED - CHECKED] ->>>>>>> reaudit-fixes-final -##### Description -The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol) contract lacks the ability to suspend a contract in an emergency and migrate assets to a new compatible `VaultPackage` contract. - -##### Recommendation -We recommend adding the `emergencyExit` function in the contract which permanently blocks contract function calls for `REWARD_OPERATOR_ROLE`, and adding the `migrate` function, which allows to move tokens and token balances to a new version of `VaultPackage`. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -The [migration](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/vault/packages/VaultPackage.sol#L82) flow is not complete. - -- After migration, `Vault` can still be used. -We recommend forbidding to use functions after migration. -- At the [`VaultPackage#L89`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/vault/packages/VaultPackage.sol#L89) `migrate` function is using balance of the `Vault` tokens instead of `deposited` mapping. In this case, during the migration, the tokens that got into the contract by accident will become deposited tokens of the new `Vault` and will be used as rewards. - -We recommend using `deposited` variable instead `balanceOf` `VaultPackage` balance. - - -#### 4. [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE-> Do at last Ask Auditor VERIFIED - CHECKED] -##### Description -In the `StakingHandlers` contract, calling the function [`updateVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L269) can cause all contract functions that work with balances and `VaultPackage` functions to be blocked. -##### Recommendation -We recommend improving this function in the following way: - -- The `VaultPackage` update must be available if the current `VaultPackage` is put into `emergencyExit` status (see recommendation to this issue). -- Updating `VaultPackage` must only take place after calling the `migrate` function in the old `VaultPackage`. -- Updating `VaultPackage` must only take place if the migration of balances to the new `VaultPackage` was successful. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/packages/StakingHandler.sol#L264) has not been fully implemented. -```solidity - function updateVault(address _vault) public override onlyRole(DEFAULT_ADMIN_ROLE) { - // enforce pausing this contract before updating the address. - // This mitigates the risk of future invalid reward claims - require(paused != 0, "require pause"); - require(_vault != address(0), "zero addr"); - require(IVault(vault).migrated(), "nt migrated"); - vault = _vault; - } -``` - -Despite checking that the `vault` is migrated, there is no validation that `_vault` is a compatible `VaultPackage`, which is the contract where the migration took place. -We recommend adding new statement that `_vault` is `VaultPackage` for migration. - - -#### [FIXED] There is no emergency suspension of the rewards payment in the `VaultPackage` contract -##### Description -In the `VaultPackage` contract there is no possibility to suspend the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31). This causes the attacker to continue taking tokens from the contract if the address with `REWARDS_OPERATOR_ROLE`, such as `StakingHandlers` contract, is compromised. - -##### Recommendation -We recommend adding the `pausable` modifier to the `payRewards` function of the `VaultPackage` contract. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] Unsafe use of the `transfer` and `transferFrom` functions in `StakingHandlers` and `VaultPackage` -##### Description -In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L34) and [VaultPackage](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) contracts there are unsafe `transfer` and `transferFrom` functions of the `ERC20` standard. The use of these functions is not recommended as not all tokens clearly comply with the `ERC20` standard, more details [here](https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca). -##### Recommendation -We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) extension from the OpenZepplin library and replace the `transfer` and `transferFrom` calls with `safeTransfer` and `safeTransferFrom`. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -<<<<<<< HEAD -<<<<<<< HEAD -#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE , Ask Auditor -Verified] -======= -#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE , VERIFIED] ->>>>>>> reaudit-fixes-final -======= -#### 11. [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`[DONE, Add safeTransfer DONE , VERIFIED - CHECKED] ->>>>>>> reaudit-fixes-final -##### Description -In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. - -##### Recommendation -We recommend: - -- adding a separate `deposit` function in the `VaultPackage` contract and make reward payments through the `deposited` parameter. -- adding a separate `withdraw` function that would allow the `DEFAULT_ADMIN_ROLE` address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). -- replacing [token transfers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) to `VaultPackage` in the `StakingHandlers` contract with calling the `deposit` function of the `VaultPackage` contract. It should have a prior `safeApprove` call to token in the `VaultPackage` contract. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -###### Oxorio's response -Recommendation has not been fully implemented. In the current version there is still no possibility to withdraw tokens that got into the contract by accident. -We recommend adding a separate withdraw function, that would allow the `DEFAULT_ADMIN_ROLE` -address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). - -<<<<<<< HEAD -<<<<<<< HEAD -#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE - Ask Auditor -VEFIRIED] -======= -#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE - Ask Auditor -VERFIED] ->>>>>>> reaudit-fixes-final -======= -#### 12. [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE - Ask Auditor -VERFIED - CHECKED] ->>>>>>> reaudit-fixes-final -##### Description -In the `StakingHandlers` contract the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function does not allocate tokens for rewards `MAIN_STREAM`, as it happens when [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) is called. This may result in the block of the `withdrawStream` function call from the `MAIN_STREAM` of tokens and rewards for some users, if the amount in `VaultPackage` is less than the amount stated in `scheduleRewards`. -##### Recommendation -We recommend moving the initialization of `MAIN_STREAM` from `initializeStaking`, that can be called when creating [`StakingProxy`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/proxy/StakingProxy.sol#L7), to the `initializeMainStream` function, which can only be called by `STREAM_MANAGER_ROLE`. Before calling this function the work of the contract must be suspended. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -The implementation of the recommendation has led to new problems. `initializeMainStream` can be reinitialized in [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/packages/StakingHandler.sol#L57). `initializeMainStream` function is missing custom initialize modifier in order to prevent it from the reinitialization. Any manager with `STREAM_MANAGER_ROLE` can create a stream without proposing it. -We recommend adding custom `stakingInitializer` modifier in order to prevent future reinitializations of the main stream. - - -#### [FIXED] Updating `rpsDuringLastClaimForLock` for inactive `stream` in the `StakingInternals` contract -##### Description -In the `StakingInternals` contract when the `_stake` function is called the [calculation of `rpsDuringLastClaimForLock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L123) is done even for inactive `streams`. This can lead to both excessive gas consumption and denial of service if the number of `streams`, active and inactive, is too large. -##### Recommendation -We recommend adding a check that the `stream`, for which the check takes place, has `ACTIVE` status. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - - -#### [FIXED] There is a possibility for a manager to remove all streams in order to steal all pending rewards in `StakingHandlers` - -##### Description - -In the contract `StakingHandlers` in the [`removeStream`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L163-L178) function a manager can remove `stream` with pending rewards for users. This will result in users losing their pending rewards. - -##### Recommendation -We recommend adding logic to check that there are no pending rewards for users in the `stream` before it can be deleted. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - - -#### [FIXED] `MINTER_ROLE` and `WHITELISTER_ROLE` have the same value in the `VMainToken` - -##### Description - -In the contract [`VMainToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L14-L15) the `MINTER_ROLE` and `WHITELISTER_ROLE` constants have the same value: -```solidity -bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); -bytes32 public constant WHITELISTER_ROLE = keccak256("MINTER_ROLE"); -``` -When the role is set, the `WHITELISTER_ROLE` variable will in fact be set to the `MINTER_ROLE`. This will result in the user getting both roles and an address with `WHITELISTER_ROLE` being able to call the `mint` and `burn` functions. - -##### Recommendation - -We recommend updating the setting of `WHITELISTER_ROLE` constant: - -```Solidity -bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); -``` -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### 5. [NEW] Transaction should be marked as `executed` if the call fails[DONE Ask Auditor -NOTDONE, check again ---!!!!!! TODO - CHECKED But CHECKAGAIN] - -##### Description - -In the contracts: - -- [`MultiSigWallet.sol#L137-L145)`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L137-L145) -- [`TimelockController.sol#L111`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) -- [`Governor.sol#L76`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) - -If the call fails, all the state changes of the contract will be reverted. It means that this call would not be marked as `executed` and can be repeated in the future, since it has enough confirmations. - -##### Recommendation -We recommend marking transaction as `executed` in all cases, removing lines with statement of revert failed transactions, and adding `data` value to event. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -For `TimelockController`, it makes sense to revert on fail of execute as it will make sure that the bad proposals are not marked executed if it fails. - -###### Oxorio's response -Recommendation was not implemented. -In the contracts - -- [`MultiSigWallet.sol#L232-L236`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/treasury/MultiSigWallet.sol#L232-L236) -- [`TimelockController.sol#L226`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/governance/TimelockController.sol#L226) -- [`Governor.sol#L430`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/governance/Governor.sol#L430) - -the failed call will lead to all the state changes of the contract to be reverted. It means that this call would not be marked as `executed` and can be repeated in the future, since it has enough confirmations. This can lead to unexpected behavior, the state of the blockchain could be changed and already executed failed transaction could be re-executed and be successful. -As for `TimelockController`, the revert on fail of `_execute` does not mark the proposal as bad proposal, e.g. if the call has logic connected with timestamps it may be reverted on the one block and be successful on the next block. - -We recommend marking transaction as `executed` in all cases, removing lines with statement of reverting the failed transactions, and adding `data` value to the event. If the status of the call is `false`, transaction should not be reverted. - -#### [FIXED] Admin role can be revoked forever by mistake in `VMainToken` - -##### Description - -In the contract `VMainToken` in the [`initToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L32) function, the value of `admin` can be the same as `msg.sender` and thus it becomes possible that an `admin` accidently revokes admin role from himself. - -##### Recommendation - -We recommend adding a check that `admin` is not equal to `msg.sender`. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] It is possible for attacker to create active locks to force users to reach the lock limit in `StakingHandlers` - -##### Description - -In the [`StakingHandler`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L180-L187) contract the attacker can create active locks for token holders with `createLockWithoutEarlyWithdraw` function by using max value for `lockPeriod` in multiple transactions. In this case user's locks limit can be reached and they will not be able to enter the staking until the end of the lock period. -##### Recommendation -We recommend: -1. Revising the logic of the `createLock` and `createLockWithoutEarlyWithdraw` functions and making a separate limit for creating a lock from a third-party address. -2. Or creating a lock from the `msg.sender` address. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### 14 .[NEW] `prohibitedEarlyWithdraw` is not set to `false` for `lockid` after unlocking in `StakingHandlers`[DONE -VERIFIED - CHECKeD] -##### Description -In the function [`createLockWithoutEarlyWithdraw`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L181) in the `StakingHandlers` contract parameter `prohibitedEarlyWithdraw` for given `lockid` is set to `true`, but it does not update to `false` after unlocking later in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions. Since the value in the `locks` array is deleted after the unlock, all new values will be assigned the value of `prohibitedEarlyWithdraw`, regardless of whether the `createLockWithoutEarlyWithdraw` or `createLock` function is called. - -##### Recommendation -We recommend setting `prohibitedEarlyWithdraw[account][lockId]` to `false` before deleting value from `locks` array in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions: - -```solidity -prohibitedEarlyWithdraw[msg.sender][lockId] = false; -``` -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -```solidity -prohibitedEarlyWithdraw[msg.sender][lockId] = false; -``` -There is no setting of `prohibitedEarlyWithdraw` to `false` for the `unlockPartially` method. - -At the same time, it can be found in the `earlyUnlock` method, but it is not needed there since this method only works when the value is already set to `false`. -We recommend adding `prohibitedEarlyWithdraw` to `unlockPartially` and removing it from `earlyUnlock` functions. - -#### [NO_ISSUE] Calling `unlock`, `earlyUnlock` and `unlockPartially` before `claimRewards` will result in loss of rewards in `StakingHandlers` -##### Description -In the contract `StakingHandlers` the following functions can cause a loss of rewards if they are called before `claimRewards`: - -- [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) -- [`earlyUnlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L207) -- [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) - -It is possible because: - -- `unlock` and `earlyUnlock` functions contain an internal call to the [`_unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L76), where `lock` with given `lockId` is [removed](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L146) -- in `unlockPartially` the `rpsDuringLastClaimForLock` for given `lockId` is [updated](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L150) - -As a result, rewards for given `lockId` will be lost. - -##### Recommendation -We recommend adding internal function `_claimRewards` and claim rewards with the calls to `unlock`, `earlyUnlock`, and `unlockPartially` functions. -##### Update -###### Fathom's response -Frontend is designed in a way that tells the user to claim all the rewards before unlocking it. So we accept the risk of rewards loss if the user ignores this notification. -You can try it on [dapp.fathom.fi](dapp.fathom.fi). - -#### [FIXED] Share weight drop formula is incorrect in `StakingInternals` - -##### Description - -In the `StakingInternals` contract [share weight drop formula](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L228) is incorrect: -```solidity -uint256 shares = amountOfTokenShares + (voteShareCoef * nVoteToken) / 1000; -uint256 slopeStart = streams[MAIN_STREAM].schedule.time[0] + ONE_MONTH; -uint256 slopeEnd = slopeStart + ONE_YEAR; -if (timestamp <= slopeStart) return shares * weight.maxWeightShares; -if (timestamp >= slopeEnd) return shares * weight.minWeightShares; -return - shares * - weight.maxWeightShares + - (shares * (weight.maxWeightShares - weight.minWeightShares) * (slopeEnd - timestamp)) / - (slopeEnd - slopeStart); -``` - -It appears that the weight of the shares should gradually fall over time from `weight.maxWeightShares` to `weight.minWeightShares`. - -However, the current formula implements a weight drop from (2*`weight.maxWeightShares` - `weight.minWeightShares`) to `weight.maxWeightShares`. - -##### Recommendation - -We recommend changing `weight.maxWeightShares` to `weight.minWeightShares` in weight drop formula: - -```solidity -return - shares * - weight.minWeightShares + - (shares * (weight.maxWeightShares - weight.minWeightShares) * (slopeEnd - timestamp)) / - (slopeEnd - slopeStart); -``` -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### 15. [NEW] Penalty can be bigger than stake in the `StakingInternals`[DONE -VERIFIED] - -##### Description - -In the contract `StakingInternals` there is a [penalty calculation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L181) in the `_earlyUnlock` function: - -```solidity -uint256 penalty = (weighingCoef * amount) / 100000; -user storage userAccount = users[account]; -userAccount.pendings[MAIN_STREAM] -= penalty; -``` - -The maximum value of the `weightingCoef` that it can take is `weight.penaltyWeightMultiplier * weight.maxWeightPenalty`. In this case, the weight parameters are not checked in any way during [initizalization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33). If they are set in a way that the product of `weight.penaltyWeightMultiplier * weight.maxWeightPenalty` is greater than `100000`, then the penalty will be greater than the amount, which in turn will lead to excessive pendings or overflow. - -##### Recommendation -We recommend adding the following check to `initializeStaking` and `updateConfig`: -```solidity -require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "Wrong penalty weight"); -``` -It is also worth moving the value of `100000` into a separate constant variable to improve the readability of the code. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -```solidity -require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "wrong weight"); -``` -The value of `weight` is checked before setting `weight = _weight`, so the result of multiplying `weight.penaltyWeightMultiplier * weight.maxWeightPenalty` will always be `0`. - -We recommend replacing the [validation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/packages/StakingInternals.sol#L32) to: -```solidity -require(_weight.penaltyWeightMultiplier * _weight.maxWeightPenalty <= 100000, "wrong weight"); -``` - -### WARNING - -#### [NO_ISSUE] Modifier `onlyOwnerOrGov` creates a complex confirmation structure in case of `Governance` calls in the `MultiSigWallet` -##### Description -The modifier [`onlyOwnerOrGov`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L29) uses the following construction: -```solidity -require(isOwner[msg.sender] || governor == msg.sender, "MultiSig: MultiSigWallet, onlyOwnerOrGov(): Neither owner nor governor"); -``` -that allows calling the following functions in the contract on behalf of Governance: - -- `submitTransaction` -- `confirmTransaction` -- `revokeConfirmation` - -However, `Governance` may commit contract calls only with [permission from `MultiSigWallet`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L173). - -The result is that, if `Governance` wants to call a transaction on a `MultiSigWallet` contract: - -- `Governance` creates `proposal` for a call to `MultiSigWallet`. -- `MultiSigWallet` after confirmation by owners must call `confirmProposal` on `Governance`. -- Then `Governance` may call one of `MultiSigWallet` functions. -- In this case, however, `MultiSigWallet` transaction execution still requires signature of `owners`. - -Schematically, is looks like the following: - -- To make a call for `MultiSigWallet` it takes steps: `Governance` -> `createProposal` -> `confirmProposal`. -- To execute `confirmProposal` it takes steps: `MultiSigWallet` -> `submitTransaction` -> `confirmTransaction` -> `executeTransaction`. -- To make a call for `MultiSigWallet` it requires the next steps from `Governance`: `Governance` -> `execute` -> `MultiSigWallet`. - -And so each function in the sequence: - -- `submitTransaction` -- `confirmTransaction` -- `revokeConfirmation` - - -##### Recommendation -We recommend removing `Governance` from this modifier and give the permission to `MultiSigWallet` administration to authorized representatives only, or review the logic of `Governance` and approving of `proposals` from `MultiSigWallet`. -##### Update -###### Fathom's response -Thats the way its designed - -#### 6. [NEW] No parameter check when adding transaction in `MultiSigWallet`[DONE - Ask Auditor VERIFIED- CHECKED] -##### Description -In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. -Based on the logic of the contract, there may be the following cases: - -- `_to` is a `EOA` address, `_value != 0,` `_data = ""`. -- `_to` is a contract. - -##### Recommendation -We recommend adding parameter checking when adding a transaction according to possible cases of using `MultiSigWallet`. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's responsea -The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/treasury/MultiSigWallet.sol#L94) is not implemented correctly. - - -```solidity -if (_to.isContract()) { - require(_data.length > 0, "no calldata for contract call"); -} else { - require(_data.length == 0 && _value > 0, "calldata for EOA call or 0 value"); -} -``` -This implementation prohibits transferring `ETH` to the contract's balance. Since in the current condition it is assumed that if `_to` is a contract, then `_data` must not be empty. - -#### [FIXED] Missing validation, that the bytecode of address `_to` did not change while running a transaction in `MultiSigWallet` -##### Description -In the functions [`confirmTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L129) and [`executeTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L137) there's no validation that the bytecode of address `_to` did not change as an EOA or smart contract. -In this case, the following situations are possible: - -- when the transaction was added with the parameter `_to` as an EOA address, i.e. with an empty bytecode, and when the transaction is executed, frontrunning may occur and the attacker may deploy to `_to` address a smart contract with malicious code, using [metamorphic contracts](https://mixbytes.io/blog/pitfalls-of-using-cteate-cteate2-and-extcodesize-opcodes) and `create2` opcodes. -- when the transaction was added with the parameter `_to` as a smart contract, and at the moment of transaction execution, frontrunning may occur, and the attacker may change the bytecode at the `_to` address for a smart contract with malicious code using [metamorphic contracts](https://mixbytes.io/blog/pitfalls-of-using-cteate-cteate2-and-extcodesize-opcodes) and `create2` opcodes. - -##### Recommendation -We recommend adding: - -- checking that `_to` is an EOA address and when `confirmTransaction` and `executeTransaction` if the contract isn't deployed into the adress, using [`isContract`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L36) from OpenZeppelin. -- checking that the contract's bytecode has not been changed, recording the bytecode hash into a separate mapping, e.g.: -```solidity -bytes32 codeHash; -assembly { - codeHash = extcodehash(_to); -} - -isWhitelistedBytesCode[_to] = codeHash; - -... -bytes32 codeHash; -assembly { codeHash := extcodehash(account) } - -return (codeHash != isWhitelistedBytesCode[_to]); -``` -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] There's no ETH balance validation when adding a non-zero transaction `_value` in `MultiSigWallet` -##### Description -In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no verifying that `MultiSigWallet` account has the necessary amount on the balance for the transaction. In case of approval by `owners` , the transaction will be approved but not executed. - -##### Recommendation -We recommend adding balance check while adding a transaction with a non-zero value `_value`. - -#### [NEW] There is no time limit for executing proposal in `Governor`[Ask ANTON -DONE Ask VERFIED - CHECKED] -##### Description -The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract has no parameters for the time limit on `proposal` execution. This can result in no longer relevant proposal being executed after a period of time. -##### Recommendation -We recommend adding the `lifetime` parameter, the runtime of `proposal`, and check it during the execution. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -We have not found a implemented corrections for this issue. -We recommend adding a lifetime parameter, the runtime of proposal, and check it during the execution. - - -#### [NO_ISSUE] There is no check for gas consumption in `Governor` -##### Description -In the [Governor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L142) contract, the `propose` function lacks a parameter and a check for gas limit for calls to `targets`. This could make it possible for a call to a vulnerable external contract to be able to loop the call and perform a DDoS attack with high gas consumption. - -##### Recommendation -Consider implementing the `gasLimit` parameter - the maximum gas amount for a call, for each of the `targets`. -##### Update -###### Fathom's response -We will have voting for proposal and multisig execution confirmation. Thats hard to DDoS there, so we won’t implement gas check. - -#### [FIXED] `confirmProposal` is possible for both active and inactive proposals in `Governor` -##### Description -In the `Governor` contract the function [`confirmProposal`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L173) can be called for both active and inactive proposals. -##### Recommendation -We recommend adding a check that the proposal is either successful or already scheduled in the `confirmProposal` function: -```solidity -ProposalState status = state(proposalId); -require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); -``` -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### 17. [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[DONE - ASK AUDITOR TODAY -VERIFIED - CHECKED] -##### Description -In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) contracts the `execute` functions do not check the `msg.value` balance value needed to execute `_targets`, which would result in gas consumption even if the amount of `ETH` is not enough. -##### Recommendation -We recommend adding: - -- a check that the `msg.value` passed to the `execute` function is greater than the total value needed for the execution of the `targets` calls in the proposal. -- a return of the remaining `ETH` balance to the sender of the transaction after the execution of `proposal`. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -The value of the transferred ETH is checked in the `TimelockController` contract when the `execute` method is executed, but is not checked for `executeBatch`, which is actually used in the contracts. -We propose refactoring this code according to the recommendation. - -#### [FIXED] There is no check for zero value for `_token`, `_multiSig` and `_timelock` in `Governor`, `GovernorTimelockControl`, `MainTokenGovernor` -##### Description -In the constructors of [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L67), [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L17) and [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L21) contracts it is possible to set zero values for `tokenAddress`, `_multiSig`, `timelock` contracts. - -This may cause that `_token`, `_multiSig` and `_timelock` can be set to a zero address by mistake and break the contract. Thus, it will not be possible to update these parameters because an update is only possible from `Governance`, and `Governance` will cannot update parameters if `_timelock` is zero. - -##### Recommendation -We recommend adding a validation that the `_token`, `_multiSig`, `_timelock` addresses in the constructor are not zero. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] There is no check for zero in `GovernorSettings._setProposalThreshold` -##### Description -In the [`_setProposalThreshold`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorSettings.sol#L59) function it is possible to set `_proposalThreshold` to `0`. This can lead to a proposer be able to create a proposal with no voting tokens on the balance, or with a minimum number of them (e.g. `1 wei`). This creates a DDoS attack threat. -##### Recommendation -We recommend adding a check that `newProposalThreshold` is not zero. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### 7. [NEW] There is no limit on the number of proposals for one proposer in `Governor`[NOTDONE, TODO - Added Blacklist, verified] -##### Description -In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. -##### Recommendation -We recommend adding a limit to the number of proposals with `active` and `pending` status. -##### Update -###### Fathom's response -`nextAcceptableProposalTimestamp[msg.sender] = block.timestamp + proposalTimeDelay;` -###### Oxorio's response -The implemented fix does not fully resolve the problem. -The Proposer can still create an unlimited number of proposals. -We recommend adding a limit for pending proposals for one user. - -Ask Auditors -> This is not desired functionality to limit pending proposals for one user. - -Make high enough proposalTimeDelay -If time, add a block for msg.sender - -#### [FIXED] A missing check that tokens are on the balance when calling the `payRewards` function in the `VaultPackage` contract -##### Description -In the `VaultPackage` contract when calling the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31) there is no processing of errors such as: - -- There is no check that tokens are on the balance. -- There is no check that the value of `amount != 0`. - -##### Recommendation -We recommend adding a check that tokens are on the balance and that `amount != 0`, and return error using `custom errors` (`revert CustomError`) or with `require`. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [NO_ISSUE] There is no limit on the maximum number of active `streams` in the `StakingHandlers` contract -##### Description -In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) contract there is no limit on the maximum number of active `streams`. This creates a situation of an uncontrolled gas consumption when dealing with contract functions and can lead to DoS. -##### Recommendation -We recommend adding a parameter that would allow to limit the maximum number of active `streams`. -##### Update -###### Fathom's response -This will be handled by Stream Manager. -###### Oxorio's response -Although it was evident that `STREAM_MANAGER_ROLE` was not a completely secure address, there have been a number of recent cases when a particular role could be compromised. -We strongly recommend to consider adding appropriate features and validations as described earlier. - - -#### [FIXED] Incorrect processing of contract modifiers `Initializable` in the `StakingHanders` contract -##### Description -The contract [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) uses the `upgradeable proxy` template, at the same time the work with the modifiers of the `Initializable` contract, which is inherited from the `AdminPausable`, is not performed correctly. -##### Recommendation -We recommend adjusting the contract according to [OpenZeppelin's recommendations](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/Initializable.sol): - -- The contract constructor must contain a call to the `_disableInitializers` function to disable contract initialization at the implementation level and prevent an attacker from using the contract's implementation -- The initializer (in the case of the `StakingHandlers` contract it is `initializeStaking`) must contain the `initializer` modifier -- The initialiser of the parent contract must be with the `onlyInitializing` modifier (in the case of the `StakingHandlers` contract, it is a call to the `pausableInit` of the [`AdminPausable`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/security/AdminPausable.sol#L28) contract) -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] It is possible for any user to call `createStream` in the `StakingHandlers` contract -##### Description -In the `StakingHandlers` contract any user can call the function [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L134) and run `stream`. This bears a risk that attackers could mislead a potential user into giving `approve` to the `StakingHandlers` contract and force them to call `createStream`. `createStream` will charge the user the necessary amount of money for the rewards. -##### Recommendation -We recommend adding a condition that `createStream` can only be called from the `streamOwner` address. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### 8. [NEW] Possible overflow with calculations[NOTDONE]//TODO [CHECKAGAIN] -##### Description -In the next lines there is a possible overflow: - -- [`RewardsLibrary.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L70) -- [`RewardsLibrary.sol#L71`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L71) -- [`RewardsLibrary.sol#L78`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L78) -- [`RewardsLibrary.sol#L8`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L84) -- [`RewardsCalculator.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L70)[DONE] -- [`RewardsCalculator.sol#L77`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L77)[DONE] -- [`RewardsCalculator.sol#L83`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L83)[DONE] -- [`RewardsInternals.sol#L15`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsInternals.sol#L15) -- [`RewardsInternals.sol#L24-L25`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsInternals.sol#L24-L25) -- [`StakingInternals.sol#L47`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L47) -- [`StakingInternals.sol#L45`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L45) -- [`StakingInternals.sol#L227-L230`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L227-L230) - -##### Recommendation -We recommend to use [`muldiv`](https://xn--2-umb.com/21/muldiv/index.html) to multiply elements safely. -We also recommend to update `voteLockCoef` [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L42) and add checks that it is not zero (to prevent division by zero) and that it is not too big in order to avoid overflow in `BoringMath`. -##### Update -###### Fathom's response -Done where feasible for contract size -###### Oxorio's response -We recommend fixing these issues completely, if there is already a problem with the size of the contract, then the code needs to be refactored. - -Here: - [`StakingInternals.sol#L45`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L45) - - Our total Supply is 1 billion. Even if we have 100 billion total supply, the above line will not overflow as, - - nVoteToken = (amount * lockPeriod * POINT_MULTIPLIER) / voteLockCoef / POINT_MULTIPLIER - - nVoteToken = 100 * 1e9(amount) * 1e9(lock period) * 1e18(Point Multiplier) / 500 (VoteLockCoef)/ 1e18 (Point Multiplier) - ~= appr.1 e38, - But since nVoteToken in appr.1e77, it will not overflow - - - - [`StakingInternals.sol#L47`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L47) - - I converted uint128 to uint256 for voteTokenBalance - - -[`StakingInternals.sol#L227-L230`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L227-L230) - - This will not overflow as maxWeightShares, minWeightShares are always less than 1e9 at max. - - Others done - -#### [NO_ISSUE] Multiple `streams` can be active at the same time with the same parameters in `StakingHandler.sol ` -##### Description -In the contract [StakingHandler]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L103-L111) it is possible to add and activate `streams` with the same parameters. This can lead to duplicate `streams` with the same parameters executed by mistake. -##### Recommendation -We recommend adding checks that `stream` is added before submitting a new one. -##### Update -###### Fathom's response -This will be handled by Stream Manager. -###### Oxorio's response -Although it was evident that `STREAM_MANAGER_ROLE` was not a completely secure address, there have been a number of recent cases when a particular role could be compromised. -We strongly recommend to consider adding appropriate features and validations as described earlier. - - -#### [NO_ISSUE] There is no limit for the amount of schedules on streams in `StakingHandlers` - -##### Description - -There is no limit for the amount of schedules on streams in the contract [`StakingHandlers`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L103-L111). This can cause the block gas limit to be exceeded. - -##### Recommendation -We recommend limiting values of `scheduleTimes` or `scheduleRewards`. -##### Update -###### Fathom's response -This will be handled by Stream Manager. -###### Oxorio's response -Although it was evident that `STREAM_MANAGER_ROLE` was not a completely secure address, there have been a number of recent cases when a particular role could be compromised. -We strongly recommend to consider adding appropriate features and validations as described earlier. - - - -#### [FIXED] It is possible to remove tokens that are used by another contract in `VaultPackage` - -##### Description -Calling the [`removeSupportedToken`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L47-L51) function in the `VaultPackage` contract removes tokens which are used in the `StakingHandler` contract to pay rewards and staked tokens. - -##### Recommendation - -We recommend adding logic to check that tokens are not used in any other contract before removing them. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -### INFO - -#### 20. [NEW] There's no logging of reverted transactions in `MultiSigWallet`[DONE, Check Again, Ask Auditor -TODAY] -##### Description -In the function [`executeConfirmation`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L144) there's no logging of failed transactions. -```solidity -(bool success, ) = transaction.to.call{ value: transaction.value }(transaction.data); -require(success, "tx failed"); -``` - -##### Recommendation -We recommend replace this construction for the next one: -```solidity -error TransactionRevered(bytes data); -... -(bool success, bytes data) = transaction.to.call{ value: transaction.value }(transaction.data); - -if (success) { - emit ExecuteTransaction(msg.sender, _txIndex); -} else { - revert TransactionRevered(data); -} -``` -This will allow monitoring of suspicious activity that involves using of `MultiSigWallet`. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -```solidity -if (success) { - emit ExecuteTransaction(msg.sender, _txIndex); -} else { - revert TransactionRevered(data); -} - -emit ExecuteTransaction(msg.sender, _txIndex); -``` -Two identical `ExecuteTransaction` events will be emitted on successful execution of the transaction. We recommend removing one from the [`MultiSigWallet#L218`]( https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/treasury/MultiSigWallet.sol#L231-L238). - - -#### [FIXED] Non-optimal packing of the `Transaction` structure in `MultiSigWallet` -##### Description - -The structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) uses a non-optimized storage layout. - -##### Recommendation -We recommend optimizing storage layout the following way: - -```solidity -struct Transaction { - address to; - bool executed; - bytes data; - uint value; - uint numConfirmations; -} -``` -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] Incorrect status check in `execute` function in `Governor` -##### Description -In the [`execute`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) function there is an incorrect check of `Proposal` status: -```solidity -require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); -``` -In the [MainTokenGovernor.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract, that inherits from `Governor`, the execution is passed to the `TimelockController` contract. For a transaction to be executed through `TimelockController` it must only have the `ProposalState.Queued` status. Otherwise the gas will be wasted and the `execute` call will be reverted. -##### Recommendation -We recommend changing the status check for `Proposal`: -```solidity -require(status == ProposalState.Queued, "Governor: proposal not successful"); -``` -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] `_minDelay` can be set to zero in `TimelockController` -##### Description -In the `TimelockController` contract the `_minDelay` parameter can be set to `0` during [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L67) and in the [`updateDelay`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L149) function. This will result in batch being able to be executed in the same block it was queued for execution. - -##### Recommendation -We recommend adding a check that `_minDelay != 0`. - -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] There is a redundant `initialized` check in `VMainToken` -##### Description -```solidity -require(!initialized, "already init"); -initialized = true; -``` -The [`initToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L24) function contains redundant code with checking and setting the value of the `initialized` parameter, since this check already exists in the `initializer` modifier in the `initToken` function. -##### Recommendation -We recommend deleting these lines. - -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] There is redundant code in the `VMainToken` contract -##### Description -The [`_mint`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L74) and [`_burn`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L78) functions in the `VMainToken` contract are redundant and essentially do not overload the parent functions. -##### Recommendation -We recommend deleting these functions. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [NO_ISSUE] The `Governor` and `TimeLockController` do not support the `ERC721` and `ERC1155` tokens -##### Description -The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contracts lack the following methods: - -```solidity -/** - * @dev See {IERC721Receiver-onERC721Received}. - */ -function onERC721Received( - address, - address, - uint256, - bytes memory -) public virtual override returns (bytes4) { - return this.onERC721Received.selector; -} - -/** - * @dev See {IERC1155Receiver-onERC1155Received}. - */ -function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory -) public virtual override returns (bytes4) { - return this.onERC1155Received.selector; -} - -/** - * @dev See {IERC1155Receiver-onERC1155BatchReceived}. - */ -function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory -) public virtual override returns (bytes4) { - return this.onERC1155BatchReceived.selector; -} -``` - -Thus `Governor` and `TimeLockController` do not support tokens with `ERC721` and `ERC1155` standards. -##### Recommendation -We recommend implementing these functions if the `Governor` and `TimeLockController` contracts require support for the `ERC721` and `ERC1155` tokens. And also create a list of trusted tokens that can work with (see above - `ERC20` standard tokens transfer possibility). -##### Update -###### Fathom's response -There is no provision for `ERC721` and `ERC1155` tokens to be deposited into the contract. - -#### [FIXED] The `addSupportedToken` and `removeSupportedToken` calls have an redundant `pausable` modifier in the `VaultPackage` contract -##### Description -In the `VaultPackage` contract the calls [`addSupportedToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L41) and [`removeSupportedToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L47) have a redundant modifier `pausable` since the calls are only possible from the `DEFAULT_ADMIN_ROLE` address and the modifier `pausable` contains the following condition -```solidity -require((paused & flag) == 0 || hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "paused contract"); -``` -where the `paused` condition will be ignored. - -##### Recommendation -We recommend reconsidering the `addSupportedToken` and `removeSupportedToken` function modifiers or removing the `pausable` modifier. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] There are no checks that `admin`, `proposers` and `executors` are not zero addresses in `TimelockController` - -##### Description - -In the contract [`TimelockController`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L49-L69) constructor there are no checks that `admin`, `proposers` and `executors` are not zero addresses. - -##### Recommendation - -We recommend adding checks that `admin`, `proposers` and `executors` are not zero addresses. - -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] Unused import of `StakingStructs` in `StakingStorage` - -##### Description - -[Import of `StakingStructs`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/StakingStorage.sol#L7) in the `StakingStorage`contract is never used. - - -##### Recommendation - -We recommend removing it to keep the codebase clean. - -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] Unused constant `ONE_MONTH` in `StakingGettersHelper` - -##### Description -The [`ONE_MONTH`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/helpers/StakingGettersHelper.sol#L13) constant in the `StakingGettersHelper` contract is never used. - -##### Recommendation -We recommend removing it to keep the codebase clean. - -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] Non-optimal storage layout for `Stream` struct in `StakingStructs` - -##### Description - -[`Stream` struct](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/StakingStructs.sol#L54-L66) in the `StakingStructs` contract has non-optimal storage layout. - -##### Recommendation -We recommend moving `StreamStatus` definition after the `rewardToken` line in the struct `Stream` in order to store values in one slot. -```solidity -struct Stream { - address owner; // stream owned by the ERC-20 reward token owner - address manager; // stream manager handled by Main stream manager role - address rewardToken; - StreamStatus status; - uint256 rewardDepositAmount; // the reward amount that has been deposited by a third party - uint256 rewardClaimedAmount; /// how much rewards have been claimed by stakers - uint256 maxDepositAmount; // maximum amount of deposit - uint256 minDepositAmount; // minimum amount of deposit - uint256 tau; // pending time prior reward release - uint256 rps; // Reward per share for a stream j>0 - Schedule schedule; -} -``` -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [FIXED] Unnecessary `'` in a `RewardsLibrary` comment - -##### Description -There is an explicit `'` in the comment in [`RewardsLibrary.sol#L82`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L82) line. - -##### Recommendation -We recommend removing `'` from the comment. - -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - - -#### [NEW] There is a typo in a comment in `StakingInternals`[DONE] - -##### Description - -There is a typo in the word "have" in the following line [`StakingInternals.sol#L95`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L95). - -```solidity -// user does not hae enough voteToken, it is still able to burn and unlock -``` - -##### Recommendation -We recommend changing it to: -```solidity -// user does not have enough voteToken, it is still able to burn and unlock -``` -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -Recommendation was not implemented, typo is still present in the word "have" in the following line [`StakingInternals#L105`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/packages/StakingInternals.sol#L105). - -We recommend changing it to: -```solidity -// user does not have enough voteToken, it is still able to burn and unlock -``` - - -#### [NEW] Redundant check for `maxDepositAmount > 0` in `RewardsCalculator`[DONE] - -##### Description - -There is a redundant check for `maxDepositAmount > 0` in the next lines: - -- [RewardsCalculator.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L21-L23) -- [RewardsLibrary.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L21-L23) - -Since `minDepositAmount` is already greater than `0` and `maxDepositAmount` must be bigger than `minDepositAmount` there is no need to check that `maxDepositAmount > 0`. - -##### Recommendation - -We recommend removing requirement of `maxDepositAmount > 0` for gas savings and improving code readability. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response -The check remains in the [`RewardsLibrary#L21`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/library/RewardsLibrary.sol#L21): - -```solidity -require(maxDepositAmount > 0, "No Max Deposit"); -``` - -#### [NO_ISSUE] It is not possible to withdraw tokens that were sent by mistake - -##### Description - -It is not possible to withdraw tokens that were sent by mistake it the following contracts: - -- [`RewardsCalculator.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol) -- [`StakingPackage.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingPackage.sol) -- [`VMainToken.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) -- [`MainToken.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/MainToken.sol) - -##### Recommendation - -We recommend adding `sweep` function to withdraw tokens that were sent by mistake. - -##### Update -###### Fathom's response -There is no provision of tokens being sent in those contract. - - -#### [FIXED] Unused import of `ReentracyGuard` in `StakingHandlers` -##### Description -There is import of [`ReentracyGuard`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L11) in the `StakingHandlers` contract but `nonReentrant` from this class is never used in `StakingHandlers`. - -##### Recommendation -We recommend removing the unused import. - -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -#### [NEW] Сustom `initializer` modifier is used instead of one from OpenZeppelin[DONE] - -##### Description - -It is better to use [Openzeppelin `initializer` ](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/Initializable.sol#L83) instead of custom modifiers in the next functions: - -- [`StakingHandler.sol#L33`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) -- [`VaultPackage.sol#L18`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L18) -- [`VMainToken.sol#L24`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L24) - -##### Recommendation - -We recommend using `initializer` and `initializable` modifiers from Openzeppelin instead of implementing custom modifiers. -##### Update -###### Fathom's response -Implemented Auditors Recommendation. -###### Oxorio's response - -The [recommendation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/vault/packages/VaultPackage.sol#L27-L28) has not been fully implemented. - -```solidity -require(!vaultInitialized, "Vault: Already Initialized"); -vaultInitialized = true; -``` - -The `vaultInitialized` variable becomes meaningless after adding the `initializer` modifier to the `initVault` function in [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/staking/vault/packages/VaultPackage.sol#L15) contract. -In [`VMainToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/daa757804b549f91904ec18af91259f7fe434883/contracts/dao/tokens/VMainToken.sol#L16) contract `initToken` function uses `initializer`, additional `bool` variable `initialized` was not removed. - -We recommend removing custom `initializer` variables and validations. - - -#### [NO_ISSUE] Stream manager, treasury manager and admin represent the same account in `StakingHandlers` - -##### Description - -In the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function in the `StakingHandlers` contract multiple roles are assigned to the same `admin` address. - -##### Recommendation -We recommend to transfer treasury role after the deployment and the staking setting. Admin and manager of the initial `stream` should be two different roles. -##### Update -###### Fathom's response - -This is initial setup to make it easier. We will share roles after some time. - -#### [NO_ISSUE] Revert message strings are too long - -##### Description - -- [`VMainToken.sol#L65-L68`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65-L68) -- [`MultiSigWallet#L30`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L30) -- [`MultiSigWallet.sol#L55`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L55) -- [`MultiSigWallet.sol#L77`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L77) - -After the revert message string is split into 32-byte sized chunks and stored in `memory` using `mstore`, the `memory` offsets are given to `revert(offset, length)`. For chunks shorter than 32 bytes, and for low `--optimize-runs` values (usually even the default value of `200`), instead of using `push32(val)` (where `val` is the 32 byte hexadecimal representation of the string with zero padding on the least significant bits) the Solidity compiler replaces it by `shl(value, short-value)`, where `short-value` does not have any zero padding. This saves the total amount of bytes in the deploy code and therefore saves deploy time cost, at the expense of extra 6 gas consumption during runtime. -This means that shorter revert strings saves deploy time costs of the contract. Note that this is not relevant for high values of `--optimize-runs` since `push32` value will not be replaced by a `shl(value, short-value)` equivalent by the Solidity compiler. - -Going back, each 32 byte chunk of the string requires an extra `mstore`. That is, additional cost for `mstore`, `memory` expansion costs, as well as stack operations. Note that this runtime cost is only relevant when the revert condition is met. - -Overall, shorter revert strings can save deploy time as well as runtime costs. - -##### Recommendation - -We recommend making revert strings shorter. -Note that if your contracts already allow Solidity `0.8.4` and above, then consider using [custom errors](https://blog.soliditylang.org/2021/04/21/custom-errors). They provide more gas efficiency and also allow developers to describe the errors in detail using [NatSpec](https://docs.soliditylang.org/en/latest/natspec-format.html). The main disadvantage of this approach is that some tooling may not have proper support for it yet. -##### Update -###### Fathom's response -Not Done, right now. Lots of changes for revert strings might be required right now. - -#### [NO_ISSUE] Unnecessary reads from storage - -##### Description - -In the next lines using `MLOAD` and `MSTORE` to cache the variable in `memory` saves more gas than `SLOAD`, since they use only 3 gas, instead of the initial 100: - -- [`MultiSigWallet.sol#L138`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L138) -- [`StakingHandler.sol#L191`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L191) -- [`StakingHandler.sol#L200`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L200) -- [`StakingHandler.sol#L210`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L210) -- [`StakingHandler.sol#L237`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L237) -- [`StakingHandler.sol#L244`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L244) - - -##### Recommendation - -We recommend caching this storage variable in `memory` to reduce unnecessary reads from storage and save more gas. -##### Update -###### Fathom's response -Not Done, increases contract size. - -#### [FIXED] Misleading check `(scheduleTimeLength > 0)` in the `RewardsCalculator` - -##### Description - -In the function [`_getStartEndScheduleIndex`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L94) in the contract `RewardsCalculator` there is the following condition: -```solidity -require(scheduleTimeLength > 0, "bad schedules"); -``` - -This condition allows `scheduleTimeLength` value to be set to 1. This can lead to [underflow](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L105) and [incorrect operation of cycles](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L98) further down the code. - -##### Recommendation - -We recommend changing it to -```solidity -require(scheduleTimeLength >= 2, "bad schedules"); -``` -or completely remove this check, since this condition is already checked in `validateStreamParameters()` when the stream is created. - -##### Update -###### Fathom's response -Implemented Auditors Recommendation. - -## Conclusion - -The following table contains the total number of issues that were found during audit: - -[FINDINGS] - -Current audit revealed 75 issues of varying degrees of importance. For each founded issue the Contractor's team made recommendations on effective solving. - - -To Ask: - -Can you verify MultiSigWallet? \ No newline at end of file diff --git a/audit-report/Fathom_DAO.md b/audit-report/Fathom_DAO.md deleted file mode 100644 index 8213286..0000000 --- a/audit-report/Fathom_DAO.md +++ /dev/null @@ -1,1048 +0,0 @@ ---- -Logo: https://i.imgur.com/ju7tCFh.png -Date: December 22, 2022 ---- - -# Fathom DAO - -## Intro - -### Disclaimer -The audit makes no statements or warranties about the utility of the code, safety of the code, suitability of the business model, investment advice, endorsement of the platform or its products, regulatory regime for the business model, or any other statements about the fitness of the contracts to purpose, or their bug free status. The audit documentation is for discussion purposes only. - -### About Oxorio - -Oxorio is a young but rapidly growing audit and consulting company in the field of the blockchain industry, providing consulting and security audits for organizations from all over the world. Oxorio has participated in multiple blockchain projects during which smart contract systems were designed and deployed by the company. - -Oxorio is the creator, maintainer, and major contributor of several blockchain projects and employs more than 5 blockchain specialists to analyze and develop smart contracts. - -Our contacts: - -- [oxor.io](https://oxor.io) -- [ping@oxor.io](mailto:ping@oxor.io) -- [Github](https://github.com/oxor-io) -- [Linkedin](https://linkedin.com/company/oxor) -- [Twitter](https://twitter.com/Oxorio_audits) - - -### Security Assessment Methodology - -A group of auditors is involved in the work on this audit. Each of them checks the provided source code independently of each other in accordance with the security assessment methodology described below: - -**1. Project architecture review** - -Study the source code manually to find errors and bugs. - -**2. Check the code for known vulnerabilities from the list** - -Conduct a verification process of the code against the constantly updated list of already known vulnerabilities maintained by the company. - -**3. Architecture and structure check of the security model** - -Study the project documentation and its comparison against the code including the study of the comments and other technical papers. - -**4. Result’s cross-check by different auditors** - -Normally the research of the project is done by more than two auditors. This is followed by a step of mutual cross-check process of the audit results between different task performers. - -**5. Report consolidation** - -Consolidation of the audited report from multiple auditors. - -**6. Reaudit of new editions** - -After the provided review and fixes from the client, the found issues are being double-checked. The results are provided in the new version of the audit. - -**7. Final audit report publication** - -The final audit version is provided to the client and also published on the official website of the company. - - -### Findings Classification - -#### Severity Level Reference -The following severity levels were assigned to the issues described in the report: - -* **CRITICAL**: A bug leading to assets theft, locked fund access, or any other loss of funds due to transfer to unauthorized parties. -* **MAJOR**: A bug that can trigger a contract failure. Further recovery is possible only by manual modification of the contract state or replacement. -* **WARNING**: A bug that can break the intended contract logic or expose it to DDoS attacks. -* **INFO**: Minor issue or recommendation reported to / acknowledged by the client's team. - -#### Status Level Reference -Based on the feedback received from the client's team regarding the list of findings discovered by the contractor, the following statuses were assigned to the findings: - -* **NEW**: Waiting for the project team's feedback. -* **FIXED**: Recommended fixes have been applied to the project code and the identified issue no longer affects the project's security. -* **ACKNOWLEDGED**: The project team is aware of this finding. Recommended fixes for this finding are planned to be made. This finding does not affect the overall security of the project. -* **NO ISSUE**: Finding does not affect the overall security of the project and does not violate the logic of its work. -* **DISMISSED**: The issue or recommendation was dismissed by the client. - - -### Project overview -Fathom is a decentralized, community governed protocol. Locking FTHM tokens in DAO vault will allow you to put forward proposals and vote on them. - -### Audit Scope - -The scope of the audit includes the following smart contracts at: - -* [Treasury contracts](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/tree/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury) -* [Governance contracts](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/tree/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance) -* [DAO Tokens contracts](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/tree/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens) -* [Staking contracts](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/tree/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking) - -The audited commit identifier is [`5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts//commit/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a) - -## Findings Report - -### CRITICAL - -#### [NEW] There's no `owners` array length validation in the constructor of `MultiSigWallet`[DONE] -##### Description -In the [MultiSigWallet\`s constructor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L76) there's no checking that the number of `owners` is less than or equal `MAX_OWNER_COUNT`. If the contract is created with `owners` with length more than `MAX_OWNER_COUNT` then that makes calls to `addOwner`, `changeRequirement` and `removeOwner` (which uses call `changeRequirement`) functions impossible because they use modifier `validRequirement` with this `require` statement: -```solidity -require(ownerCount <= MAX_OWNER_COUNT && _required <= ownerCount && _required != 0 && ownerCount != 0, "MultiSig: Invalid requirement"); -_; -``` - -##### Recommendation -We recommend adding `owners` array length validation to `MultiSigWallet` constructor: -```solidity -require(_owners.length <= MAX_OWNER_COUNT, "owners limit reached"); -``` - -#### [NEW] Adding a new owner doesn't change necessary amount of signatures in `MultiSigWallet`[DONE] -##### Description -In the function [`addOwner`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L108) the owner is added without changing the parameter `numConfirmationsRequired`. In a situation, for example, where signatures of 2 out of 4 owners are required, it results in that when the owner is added, there will be 2 out of 5, and it requires less than a half of the signatures to manage the functions of the contract, so the contract could be compromised. - -##### Recommendation -We recommend adding this call into function `addOwner`: -```solidity -changeRequirement(numConfirmationsRequired+1); -``` - - -#### [NEW] Removing owner without `revokeConfirmation` transaction in `MultiSigWallet`[DONE] -##### Description -In the function [`removeOwner`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L96) the owner is being removed without revocation of transaction signatures, where they've signed. This creates a situation where the signatures of non-existent owners may be used. For example, like in the following scenario: - -1. There are signatures of 3 out of 5 owners. -2. 3 owners opposed the signing of the transaction, and 2 owners approved it. -3. 3 owners called `removeOwner` for 2 owners, who previously signed the transaction. -4. Then, one of the 3 remaining owners , using signatures of non-existent owners are able to execute the transaction. - -##### Recommendation -We recommend adding signature revocation mechanisms for signatures of the removed owners to the function `removeOwner`. - -#### [NEW] There is no function that implements the `_cancel` proposal in `MainTokenGovernor`[DONE] -##### Description -The contract [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) lacks a function that would implement the internal function [`_cancel`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L91), that allows you to cancel the execution of `proposal` with `TimelockController`. This can make it impossible to cancel the execution of a potentially dangerous call. -##### Recommendation -We recommend adding logic that would allow you to cancel the execution of `proposal` and call the internal function `_cancel`. - - -#### [NEW] Changing the `timelock` address may cause re-execution of the proposals in `GovernorTimelockControl`[DONE,Is this true Max Ji. Feels not] -##### Description -A change of the `timelock` parameter in the [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L22) contract can lead to already executed `proposals` being able to be executed again. This is connected to the fact that the execution status of the transaction is saved only in the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, and the `GovernorTimelockControl` contract makes calls to the `TimelockController` functions to get the `proposals` status in the [`state`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L50) function. -##### Recommendation -We recommend adding a separate mapping to the `GovernorTimelockControl` contract that would save information about the status of `proposal` and functions that would allow to update that status. -#### [NEW] The `initVault` and `initAdminAndOperator` functions can be initialized from any address in the `VaultPackage` contract[DONE, checkAgain] -##### Description -In the `VaultPackage` contract the [`initVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L18) and [`initAdminAndOperator`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L26) functions can be called from any address. This could result in a potential attacker being able to intercept control for both `initVault` and `initAdminAndOperator` calls. -##### Recommendation -We suggest two solutions to this problem: - -- Combine the `initVault` and `initAdminAndOperator` functions into one `initialize` function and pass `calldata` to the [VaultProxy](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/proxy/VaultProxy.sol#L7) constructor in the `_data` parameter. -- Make a call to the `initVault` function on behalf of the `DEFAULT_ADMIN_ROLE`, and pass the `initVault` parameters just as `calldata` in the [VaultProxy](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/proxy/VaultProxy.sol#L7) constructor. - - -#### [NEW] There is no check that `stream` is active in the `StakingHandler` contract[DONE] -##### Description -In the `StakingHandler` contract the [`withdrawAllStreams`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L243) and [`withdrawStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L236) functions do not have a check that `stream` is active. In the case of `withdrawAllStreams` this causes the function to use the entire `streams` array each time with active and inactive `streams` and, if there are not enough tokens on `VaultPackage`, the entire transaction will be `reverted`. In the case of `withdrawStream`, this can lead to `reverted` transaction, or unauthorized withdrawal of tokens from `VaultPackage`. - -##### Recommendation -We recommend adding to the `withdrawAllStreams` and `withdrawStream` functions a check that the output from `stream` has the status `ACTIVE`. - - -#### [NEW] Calling the `updateConfig` function may block the work of the `StakingHandlers` contract[Could you clarify this more? What does migration actually mean, upgrade or moving to completely new contract address?,Ask Anton, just remove updateConfig?] -##### Description -Calling the function [`updateConfig`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L252) in the `StakingHandler` contract can disrupt its work. This is possible for the following reasons: - -- There is no validation of `_weight` values. `_weight` can be equal to `0` and break the calculation of `share` in `streams` for staking holders. This will result in incorrect calculation of the repayment of staked tokens and rewards when exiting the stacking, which will block the work of the contract. -- Updating the `voteToken` parameter will cause the contract to try to burn new `voteToken` tokens that are not on the balance when [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) is called. -- Updating the parameters `rewardsCalculator`, `voteShareCoef`, `maxLockPeriod`, `maxLockPositions` will also lead to incorrect calculations and contract blocking. - -##### Recommendation -We recommend discarding the `updateConfig` function and consider mechanisms for stacking migration to a new contract with a suspension of the contract work during migration, e.g. `emergencyExit`. - -### MAJOR - -#### [NEW] In `MultiSigWallet` there's no parameter defining minimum amount of signatures[NOTDONE but would have bad impact on test, MAXJI] -> DONE -##### Description -The parameter [`_numConfirmationsRequired`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L77) is checked in the constructor and in the function [`changeRequirement`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L116), that is not equal to `0`, however, when multi-signature is set, it allows the value `1`, and the contract may be used by one of the `owners`. - -##### Recommendation -We recommend adding minimum quantity constant for necessary signatures, e.g. `MIN_CONFIRMATIONS` and check if the set value is greater than or equal to `MIN_CONFIRMATIONS`. - -#### [NEW] Transaction does not have a lifetime parameter in `MultiSigWallet`[DONE] -##### Description -In the structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) there's no lifetime parameter `expired`, which is responsible for the period of time during which the transaction must be executed. Since transactions may be executed at random time and are not removed over time, frozen, previously not approved transactions can be executed after a certain time and cause an undesirable effect. -##### Recommendation -We recommend adding an individual parameter, which is responsible for the maximum time until the transaction can be executed, e.g. `expired` and check it before running transactions. - -#### [NEW] Governance can delete `TimelockAdmin` and the contract will lose its control in `TimelockController`[DONE, MAXJI] -##### Description -In the [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contract, Governance can take away the `TIMELOCK_ADMIN_ROLE` rights from the address `admin`. In the case of an attack on `Governance` and `Council` this would make it impossible to revoke the role from the captured contracts. -##### Recommendation -We recommend to consider a permissions policy or add the `DEFAULT_ADMIN_ROLE` for `admin` to be able to revoke the role in case of an attack. - - -#### [NEW] There is no validation for `maxTargets` when executing in `Governor` -##### Description[DONE] -In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L142) function there is no validation of the maximum number of `targets`. This can cause `proposal` to have so many calls to external contracts that the execution transaction will face a "gas bomb" effect. This means a large amount of gas consumption or restricted gas limit block. -##### Recommendation -We recommend including the `maxTargets` parameter for `_targets`, the maximum number of `_targets` in the `proposal`. - - -#### [NEW] There is no possibility to update `multisig` in `Governor`[DONE] -##### Description -In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L34) contract there is no possibility to perform a migration to a new `multisig`. For example to a new version of the contract. -##### Recommendation -We recommend adding the `updateMultisig` function, but so that only the old `multisig` could call it. - - -#### [NEW] There is no emergency shutdown mode in `Governor`[NOTDONE, how to do? ask more feedback, MAXJI] -##### Description -There is no possibility in the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract to put it into an emergency shutdown status. If one of the `TimelockController`, `MultiSigWallet` contracts is compromised, Governance will not be able to perform an emergency shut-down of proposals execution and stop contracts. -##### Recommendation -We recommend adding the `emergencyExit` function to the contract, which can be called by Governance by majorit fy vote without confirmation with `multisig`. The function can be called once, its call stops the work of the contract. After calling this function, recovery is only possible by migrating to a new contract. - - -#### [NEW] It is possible to set a null address in `GovernorTimelockControl` when updating `timelock`.[DONE] -##### Description -In the `GovernorTimelockControl` contract it is possible to set a null address when calling the function [`_updateTimelock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L111). This can make the execution of `proposals` not possible since it is done through `timelock`. It will be also not possible to recover or change `timelock`, since it needs the corresponding proposal to be executed, which is also not possible with a zero `timelock`. -##### Recommendation -We recommend adding a check that the address `newTimelock != address(0)` - - -#### [NEW] There is no validation for null values for `newQuorumNumerator` in `GovernorVotesQuorumFraction`[DONE,Ask Max] -##### Description -In the `GovernorVotesQuorumFraction` contract in the [`_updateQuorumNumerator`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorVotesQuorumFraction.sol#L55) function it is possible to set `_quorumNumerator` to `0` value, which would lead to a complete voting stop. -##### Recommendation -We recommend adding a constant with the minimum allowable value of `_quorumNumerator` and perform a corresponding check in the `_updateQuorumNumerator` function. - - -#### [NEW] When `MINTER_ROLE` is added to `VMainToken`, the `isWhiteListed` list does not update[DONE,Check Again, TODO] -##### Description -In the [VMainToken](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) contract, for mint tokens, calling account, in addition to having `MINTER_ROLE` rights, must also be in the `isWhiteListed` list, since the mint function calls `_mint,` which contains [`_beforeTokenTransfer`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65) call. -When `_beforeTokenTransfer` is called, it checks that the `msg.sender` address is in the `isWhiteListed` list. -In the case of `mint`, it is the address with the `MINTER_ROLE` rights. -The administrator can grant/revoke `MINTER_ROLE` from an address by calling `grantRole`/`revokeRole`, but the `isWhitelisted` list remains unchanged - the old address stays in the list while the new one is never added. -This creates a risk that if `MINTER_ROLE` is compromised by an attacker, the admin will not be able to correctly revoke his rights, and the attacker can make a `transfer` of tokens to unauthorized addresses. -##### Recommendation -We recommend adding separate functions to grant and revoke the `MINTER_ROLE`, which will also add and remove addresses from the `isWhitelisted` list. - - -#### [NEW] There is no possibility to transfer standard `ERC20` tokens from the Governance balance in `MainTokenGovernor`[ASK MAXJI about targets] -##### Description -In the [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract there is no possibility to transfer tokens of the `ERC20` standard from the balance of Governance, because execution of the transaction is actually passed to the `TimelockController`. -##### Recommendation -We recommend fixing the possibility of withdrawal of tokens of the `ERC20` standard from the balance of Governance. This can be done in the following way: - -- It is a must to implement the `addSupportingTokens` function due to the fact that various tokens of the `ERC20` standard can be transferred to the Governance balance. Governance must work only with trusted tokens like USDT, USDC, etc. This function will make it possible to create a list of trusted tokens. Adding a token should only be done through Governance. -- Add a check to the `execute` function to confirm that `_target` is the contract address from the trusted tokens. And only in this case pass it to the `TimelockController` address. - -#### [NEW] There is no option to migrate to another contract in the `VaultPackage` contract[DONE but, ask anton] -##### Description -The [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol) contract lacks the ability to suspend a contract in an emergency and migrate assets to a new compatible `VaultPackage` contract. - -##### Recommendation -We recommend adding the `emergencyExit` function in the contract which permanently blocks contract function calls for `REWARD_OPERATOR_ROLE`, and adding the `migrate` function, which allows to move tokens and token balances to a new version of `VaultPackage`. - -#### [NEW] There is a DoS possibility when calling `updateVault` in the `StakingHandlers` contract[NOTDONE, please explain more] -##### Description -In the `StakingHandlers` contract, calling the function [`updateVault`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L269) can cause all contract functions that work with balances and `VaultPackage` functions to be blocked. -##### Recommendation -We recommend improving this function in the following way: - -- The `VaultPackage` update must be available if the current `VaultPackage` is put into `emergencyExit` status (see recommendation to this issue). -- Updating `VaultPackage` must only take place after calling the `migrate` function in the old `VaultPackage`. -- Updating `VaultPackage` must only take place if the migration of balances to the new `VaultPackage` was successful. - -#### [NEW] There is no emergency suspension of the rewards payment in the `VaultPackage` contract[DONE] -##### Description -In the `VaultPackage` contract there is no possibility to suspend the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31). This causes the attacker to continue taking tokens from the contract if the address with `REWARDS_OPERATOR_ROLE`, such as `StakingHandlers` contract, is compromised. - -##### Recommendation -We recommend adding the `pausable` modifier to the `payRewards` function of the `VaultPackage` contract. - -#### [NEW] Unsafe use of the `transfer` and `transferFrom` functions in `StakingHandlers` and `VaultPackage`[DONE] -##### Description -In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L34) and [VaultPackage](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) contracts there are unsafe `transfer` and `transferFrom` functions of the `ERC20` standard. The use of these functions is not recommended as not all tokens clearly comply with the `ERC20` standard, more details [here](https://medium.com/coinmonks/missing-return-value-bug-at-least-130-tokens-affected-d67bf08521ca). -##### Recommendation -We recommend using the [`SafeERC20`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/token/ERC20/utils/SafeERC20.sol) extension from the OpenZepplin library and replace the `transfer` and `transferFrom` calls with `safeTransfer` and `safeTransferFrom`. - -#### [NEW] Tokens that get into the `VaultPackage` balance can be used to withdraw rewards in the contract `VaultPackage`{NOTDONE, Ask Anton} -##### Description -In the [`VaultPackage`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L12) contract tokens that get into the balance of the contract can be used for rewards payment from streams in [StakingHandlers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol). This results in tokens, that get on the balance by mistake and/or intentionally, not being able to be withdrawn from the contract. - -##### Recommendation -We recommend: - -- adding a separate `deposit` function in the `VaultPackage` contract and make reward payments through the `deposited` parameter. -- adding a separate `withdraw` function that would allow the `DEFAULT_ADMIN_ROLE` address to take excess tokens away (both `supportedTokens` and tokens that are not on the list). -- replacing [token transfers](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) to `VaultPackage` in the `StakingHandlers` contract with calling the `deposit` function of the `VaultPackage` contract. It should have a prior `safeApprove` call to token in the `VaultPackage` contract. - -#### [NEW] Calling `initializeStaking` in the `StakingHandlers` contract does not allocate rewards for `MAIN_STREAM` in `VaultPackage`[DONE] -##### Description -In the `StakingHandlers` contract the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function does not allocate tokens for rewards `MAIN_STREAM`, as it happens when [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L152) is called. This may result in the block of the `withdrawStream` function call from the `MAIN_STREAM` of tokens and rewards for some users, if the amount in `VaultPackage` is less than the amount stated in `scheduleRewards`. -##### Recommendation -We recommend moving the initialization of `MAIN_STREAM` from `initializeStaking`, that can be called when creating [`StakingProxy.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/proxy/StakingProxy.sol#L7), to the `initializeMainStream` function, which can only be called by `STREAM_MANAGER_ROLE`. Before calling this function the work of the contract must be suspended. - -#### [NEW] Updating `rpsDuringLastClaimForLock` for inactive `stream` in the `StakingInternals` contract[DONE] -##### Description -In the `StakingInternals` contract when the `_stake` function is called the [calculation of `rpsDuringLastClaimForLock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L123) is done even for inactive `streams`. This can lead to both excessive gas consumption and denial of service if the number of `streams`, active and inactive, is too large. -##### Recommendation -We recommend adding a check that the `stream`, for which the check takes place, has `ACTIVE` status. - -#### [NEW] There is a possibility for a manager to remove all streams in order to steal all pending rewards in `StakingHandlers` [DONE] - -##### Description - -In the contract `StakingHandlers` in the [`removeStream`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L163-L178) function a manager can remove `stream` with pending rewards for users. This will result in users losing their pending rewards. - -##### Recommendation -We recommend adding logic to check that there are no pending rewards for users in the `stream` before it can be deleted. - - -#### [NEW] `MINTER_ROLE` and `WHITELISTER_ROLE` have the same value in the `VMainToken`[DONE] - -##### Description - -In the contract [`VMainToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L14-L15) the `MINTER_ROLE` and `WHITELISTER_ROLE` constants have the same value: -```solidity -bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE"); -bytes32 public constant WHITELISTER_ROLE = keccak256("MINTER_ROLE"); -``` -When the role is set, the `WHITELISTER_ROLE` variable will in fact be set to the `MINTER_ROLE`. This will result in the user getting both roles and an address with `WHITELISTER_ROLE` being able to call the `mint` and `burn` functions. - -##### Recommendation - -We recommend updating the setting of `WHITELISTER_ROLE` constant: - -```Solidity -bytes32 public constant WHITELISTER_ROLE = keccak256("WHITELISTER_ROLE"); -``` - - -#### [NEW] Transaction should be marked as `executed` if the call fails[DONE, Ask] - -##### Description - -In the contracts: - -- [`MultiSigWallet.sol#L137-L145)`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L137-L145) -- [`TimelockController.sol#L111`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) -- [`Governor.sol#L76`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) - -If the call fails, all the state changes of the contract will be reverted. It means that this call would not be marked as `executed` and can be repeated in the future, since it has enough confirmations. - -##### Recommendation -We recommend marking transaction as `executed` in all cases, removing lines with statement of revert failed transactions, and adding `data` value to event. - - -#### [NEW] Admin role can be revoked forever by mistake in `VMainToken`[DONE] - -##### Description - -In the contract `VMainToken` in the [`initToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L32) function, the value of `admin` can be the same as `msg.sender` and thus it becomes possible that an `admin` accidently revokes admin role from himself. - -##### Recommendation - -We recommend adding a check that `admin` is not equal to `msg.sender`. - - -#### [NEW] It is possible for attacker to create active locks to force users to reach the lock limit in `StakingHandlers`[NOTDONE] - -##### Description - -In the [`StakingHandler`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L180-L187) contract the attacker can create active locks for token holders with `createLockWithoutEarlyWithdraw` function by using max value for `lockPeriod` in multiple transactions. In this case user's locks limit can be reached and they will not be able to enter the staking until the end of the lock period. - -##### Recommendation - -We recommend: - -1. Revising the logic of the `createLock` and `createLockWithoutEarlyWithdraw` functions and making a separate limit for creating a lock from a third-party address. -2. Or creating a lock from the `msg.sender` address. - -#### [NEW] `prohibitedEarlyWithdraw` is not set to `false` for `lockid` after unlocking in `StakingHandlers`[DONE] -##### Description -In the function [`createLockWithoutEarlyWithdraw`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L181) in the `StakingHandlers` contract parameter `prohibitedEarlyWithdraw` for given `lockid` is set to `true`, but it does not update to `false` after unlocking later in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions. Since the value in the `locks` array is deleted after the unlock, all new values will be assigned the value of `prohibitedEarlyWithdraw`, regardless of whether the `createLockWithoutEarlyWithdraw` or `createLock` function is called. - -##### Recommendation -We recommend setting `prohibitedEarlyWithdraw[account][lockId]` to `false` before deleting value from `locks` array in the [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) and [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) functions: - -```solidity -prohibitedEarlyWithdraw[msg.sender][lockId] = false; -``` - -#### [NEW] Calling `unlock`, `earlyUnlock` and `unlockPartially` before `claimRewards` will result in loss of rewards in `StakingHandlers`[Frontend Will Handle] -##### Description -In the contract `StakingHandlers` the following functions can cause a loss of rewards if they are called before `claimRewards`: - -- [`unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L189) -- [`earlyUnlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L207) -- [`unlockPartially`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L198) - -It is possible because: - -- `unlock` and `earlyUnlock` functions contain an internal call to the [`_unlock`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L76), where `lock` with given `lockId` is [removed](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L146) -- in `unlockPartially` the `rpsDuringLastClaimForLock` for given `lockId` is [updated](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L150) - -As a result, rewards for given `lockId` will be lost. - -##### Recommendation -We recommend adding internal function `_claimRewards` and claim rewards with the calls to `unlock`, `earlyUnlock`, and `unlockPartially` functions. - - -#### [NEW] Share weight drop formula is incorrect in `StakingInternals`[DONE] - -##### Description - -In the `StakingInternals` contract [share weight drop formula](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L228) is incorrect: -```solidity -uint256 shares = amountOfTokenShares + (voteShareCoef * nVoteToken) / 1000; -uint256 slopeStart = streams[MAIN_STREAM].schedule.time[0] + ONE_MONTH; -uint256 slopeEnd = slopeStart + ONE_YEAR; -if (timestamp <= slopeStart) return shares * weight.maxWeightShares; -if (timestamp >= slopeEnd) return shares * weight.minWeightShares; -return - shares * - weight.maxWeightShares + - (shares * (weight.maxWeightShares - weight.minWeightShares) * (slopeEnd - timestamp)) / - (slopeEnd - slopeStart); -``` - -It appears that the weight of the shares should gradually fall over time from `weight.maxWeightShares` to `weight.minWeightShares`. - -However, the current formula implements a weight drop from (2*`weight.maxWeightShares` - `weight.minWeightShares`) to `weight.maxWeightShares`. - -##### Recommendation - -We recommend changing `weight.maxWeightShares` to `weight.minWeightShares` in weight drop formula: - -```solidity -return - shares * - weight.minWeightShares + - (shares * (weight.maxWeightShares - weight.minWeightShares) * (slopeEnd - timestamp)) / - (slopeEnd - slopeStart); -``` - - -#### [NEW] Penalty can be bigger than stake in the `StakingInternals`[DONE] - -##### Description - -In the contract `StakingInternals` there is a [penalty calculation](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L181) in the `_earlyUnlock` function: - -```solidity -uint256 penalty = (weighingCoef * amount) / 100000; -user storage userAccount = users[account]; -userAccount.pendings[MAIN_STREAM] -= penalty; -``` - -The maximum value of the `weightingCoef` that it can take is `weight.penaltyWeightMultiplier * weight.maxWeightPenalty`. In this case, the weight parameters are not checked in any way during [initizalization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33). If they are set in a way that the product of `weight.penaltyWeightMultiplier * weight.maxWeightPenalty` is greater than `100000`, then the penalty will be greater than the amount, which in turn will lead to excessive pendings or overflow. - -##### Recommendation -We recommend adding the following check to `initializeStaking()` and `updateConfig()`: -```solidity -require(weight.penaltyWeightMultiplier * weight.maxWeightPenalty <= 100000, "Wrong penalty weight"); -``` -It is also worth moving the value of `100000` into a separate constant variable to improve the readability of the code. - - -### WARNING - -#### [NEW] Modifier `onlyOwnerOrGov` creates a complex confirmation structure in case of `Governance` calls in the `MultiSigWallet.sol`[Ask Max] -##### Description -The modifier [`onlyOwnerOrGov`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L29) uses the following construction: -```solidity -require(isOwner[msg.sender] || governor == msg.sender, "MultiSig: MultiSigWallet, onlyOwnerOrGov(): Neither owner nor governor"); -``` -that allows calling the following functions in the contract on behalf of Governance: - -- `submitTransaction` -- `confirmTransaction` -- `revokeConfirmation` - -However, `Governance` may commit contract calls only with [permission from `MultiSigWallet`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L173). - -The result is that, if `Governance` wants to call a transaction on a `MultiSigWallet` contract: - -- `Governance` creates `proposal` for a call to `MultiSigWallet`. -- `MultiSigWallet` after confirmation by owners must call `confirmProposal` on `Governance`. -- Then `Governance` may call one of `MultiSigWallet` functions. -- In this case, however, `MultiSigWallet` transaction execution still requires signature of `owners`. - -Schematically, is looks like the following: - -- To make a call for `MultiSigWallet` it takes steps: `Governance` -> `createProposal` -> `confirmProposal`. -- To execute `confirmProposal` it takes steps: `MultiSigWallet` -> `submitTransaction` -> `confirmTransaction` -> `executeTransaction`. -- To make a call for `MultiSigWallet` it requires the next steps from `Governance`: `Governance` -> `execute` -> `MultiSigWallet`. - -And so each function in the sequence: - -- `submitTransaction` -- `confirmTransaction` -- `revokeConfirmation` - - -##### Recommendation -We recommend removing `Governance` from this modifier and give the permission to `MultiSigWallet` administration to authorized representatives only, or review the logic of `Governance` and approving of `proposals` from `MultiSigWallet`. - -#### [NEW] No parameter check when adding transaction in `MultiSigWallet`[Ask Max] -##### Description -In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no validation of address `_to` to be the contract. -Based on the logic of the contract, there may be the following cases: - -- `_to` is a `EOA` address, `_value != 0,` `_data = ""`. -- `_to` is a contract. - -##### Recommendation -We recommend adding parameter checking when adding a transaction according to possible cases of using `MultiSigWallet`. - -#### [NEW] Missing validation, that the bytecode of address `_to` did not change while running a transaction in `MultiSigWallet`[DONE] -##### Description -In the functions [`confirmTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L129) and [`executeTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L137) there's no validation that the bytecode of address `_to` did not change as an EOA or smart contract. -In this case, the following situations are possible: - -- when the transaction was added with the parameter `_to` as an EOA address, i.e. with an empty bytecode, and when the transaction is executed, frontrunning may occur and the attacker may deploy to `_to` address a smart contract with malicious code, using [metamorphic contracts](https://mixbytes.io/blog/pitfalls-of-using-cteate-cteate2-and-extcodesize-opcodes) and `create2` opcodes. -- when the transaction was added with the parameter `_to` as a smart contract, and at the moment of transaction execution, frontrunning may occur, and the attacker may change the bytecode at the `_to` address for a smart contract with malicious code using [metamorphic contracts](https://mixbytes.io/blog/pitfalls-of-using-cteate-cteate2-and-extcodesize-opcodes) and `create2` opcodes. - -##### Recommendation -We recommend adding: - -- checking that `_to` is an EOA address and when `confirmTransaction` and `executeTransaction` if the contract isn't deployed into the adress, using [`isContract`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/utils/Address.sol#L36) from OpenZeppelin. -- checking that the contract's bytecode has not been changed, recording the bytecode hash into a separate mapping, e.g.: -```solidity -bytes32 codeHash; -assembly { - codeHash = extcodehash(_to); -} - -isWhitelistedBytesCode[_to] = codeHash; - -... -bytes32 codeHash; -assembly { codeHash := extcodehash(account) } - -return (codeHash != isWhitelistedBytesCode[_to]); -``` - -#### [NEW] There's no ETH balance validation when adding a non-zero transaction `_value` in `MultiSigWallet`[DONE] -##### Description -In the function [`submitTransaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L121) there's no verifying that `MultiSigWallet` account has the necessary amount on the balance for the transaction. In case of approval by `owners` , the transaction will be approved but not executed. - -##### Recommendation -We recommend adding balance check while adding a transaction with a non-zero value `_value`. - -#### [NEW] There is no time limit for executing proposal in `Governor.sol`[DONE] -##### Description -The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) contract has no parameters for the time limit on `proposal` execution. This can result in no longer relevant proposal being executed after a period of time. -##### Recommendation -We recommend adding the `lifetime` parameter, the runtime of `proposal`, and check it during the execution. - - -#### [NEW] There is no check for gas consumption in `Governor`[ASK ANTON FOR MAX GAS LIMIT] -##### Description -In the [Governor](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L142) contract, the `propose` function lacks a parameter and a check for gas limit for calls to `targets`. This could make it possible for a call to a vulnerable external contract to be able to loop the call and perform a DDoS attack with high gas consumption. - -##### Recommendation -Consider implementing the `gasLimit` parameter - the maximum gas amount for a call, for each of the `targets`. - - -#### [NEW] `confirmProposal` is possible for both active and inactive proposals in `Governor`[DONE] -##### Description -In the `Governor` contract the function [`confirmProposal`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L173) can be called for both active and inactive proposals. -##### Recommendation -We recommend adding a check that the proposal is either successful or already scheduled in the `confirmProposal` function: -```solidity -ProposalState status = state(proposalId); -require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); -``` - -#### [NEW] There is no check for the `msg.value` value available for execution in `Governor` and `TimelockController`[Ask ANton,MAXJI] -##### Description -In the [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L111) contracts the `execute` functions do not check the `msg.value` balance value needed to execute `_targets`, which would result in gas consumption even if the amount of `ETH` is not enough. -##### Recommendation -We recommend adding: - -- a check that the `msg.value` passed to the `execute` function is greater than the total value needed for the execution of the `targets` calls in the proposal. -- a return of the remaining `ETH` balance to the sender of the transaction after the execution of `proposal`. - -#### [NEW] There is no check for zero value for `_token`, `_multiSig` and `_timelock` in `Governor`, `GovernorTimelockControl`, `MainTokenGovernor`[DONE] -##### Description -In the constructors of [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L67), [`GovernorTimelockControl`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorTimelockControl.sol#L17) and [`MainTokenGovernor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L21) contracts it is possible to set zero values for `tokenAddress`, `_multiSig`, `timelock` contracts. - -This may cause that `_token`, `_multiSig` and `_timelock` can be set to a zero address by mistake and break the contract. Thus, it will not be possible to update these parameters because an update is only possible from `Governance`, and `Governance` will cannot update parameters if `_timelock` is zero. - -##### Recommendation -We recommend adding a validation that the `_token`, `_multiSig`, `_timelock` addresses in the constructor are not zero. - -#### [NEW] There is no check for zero in `GovernorSettings._setProposalThreshold`[DONE] -##### Description -In the [`_setProposalThreshold`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/extensions/GovernorSettings.sol#L59) function it is possible to set `_proposalThreshold` to `0`. This can lead to a proposer be able to create a proposal with no voting tokens on the balance, or with a minimum number of them (e.g. `1 wei`). This creates a DDoS attack threat. -##### Recommendation -We recommend adding a check that `newProposalThreshold` is not zero. - -#### [NEW] There is no limit on the number of proposals for one proposer in `Governor`[Ask MAXJI] -##### Description -In the `Governor` contract in the [`propose`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol#L36) function there is no limit on the number of proposals for one proposer. Thus, a proposer can perform a DDoS attack and create an unlimited number of requests, even in one single block. -##### Recommendation -We recommend adding a limit to the number of proposals with `active` and `pending` status. - -#### [NEW] A missing check that tokens are on the balance when calling the `payRewards` function in the `VaultPackage` contract[NOTDONE] -##### Description -In the `VaultPackage` contract when calling the function [`payRewards`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L31) there is no processing of errors such as: - -- There is no check that tokens are on the balance. -- There is no check that the value of `amount != 0`. - -##### Recommendation -We recommend adding a check that tokens are on the balance and that `amount != 0`, and return error using `custom errors` (`revert CustomError`) or with `require`. - - -#### [NEW] There is no limit on the maximum number of active `streams` in the `StakingHandlers` contract[NOTNEEDED] -##### Description -In the [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) contract there is no limit on the maximum number of active `streams`. This creates a situation of an uncontrolled gas consumption when dealing with contract functions and can lead to DoS. -##### Recommendation -We recommend adding a parameter that would allow to limit the maximum number of active `streams`. - - -#### [NEW] Incorrect processing of contract modifiers `Initializable` in the `StakingHanders` contract[DONE] -##### Description -The contract [`StakingHandlers`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol) uses the `upgradeable proxy` template, at the same time the work with the modifiers of the `Initializable` contract, which is inherited from the `AdminPausable`, is not performed correctly. -##### Recommendation -We recommend adjusting the contract according to [OpenZeppelin's recommendations](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/Initializable.sol): - -- The contract constructor must contain a call to the `_disableInitializers` function to disable contract initialization at the implementation level and prevent an attacker from using the contract's implementation[DONE] -- The initializer (in the case of the `StakingHandlers` contract it is `initializeStaking`) must contain the `initializer` modifier[DONE] -- The initialiser of the parent contract must be with the `onlyInitializing` modifier (in the case of the `StakingHandlers` contract, it is a call to the `pausableInit` of the [`AdminPausable`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/common/security/AdminPausable.sol#L28) contract) - -#### [NEW] It is possible for any user to call `createStream` in the `StakingHandlers` contract[DONE] -##### Description -In the `StakingHandlers` contract any user can call the function [`createStream`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L134) and run `stream`. This bears a risk that attackers could mislead a potential user into giving `approve` to the `StakingHandlers` contract and force them to call `createStream`. `createStream` will charge the user the necessary amount of money for the rewards. -##### Recommendation -We recommend adding a condition that `createStream` can only be called from the `streamOwner` address. - -#### [NEW] Possible overflow with calculations -##### Description[NOTDONE] -In the next lines there is a possible overflow: - -- [`RewardsLibrary.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L70) -- [`RewardsLibrary.sol#L71`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L71) -- [`RewardsLibrary.sol#L78`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L78) -- [`RewardsLibrary.sol#L8`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L84) -- [`RewardsCalculator.sol#L70`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L70) -- [`RewardsCalculator.sol#L77`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L77) -- [`RewardsCalculator.sol#L83`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L83) -- [`RewardsInternals.sol#L15`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsInternals.sol#L15) -- [`RewardsInternals.sol#L24-L25`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsInternals.sol#L24-L25) -- [`StakingInternals.sol#L47`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L47) -- [`StakingInternals.sol#L45`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L45) -- [`StakingInternals.sol#L227-L230`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L227-L230) - -##### Recommendation -We recommend to use [`muldiv`](https://xn--2-umb.com/21/muldiv/index.html) to multiply elements safely. -We also recommend to update `voteLockCoef` [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L42) and add checks that it is not zero (to prevent division by zero) and that it is not too big in order to avoid overflow in `BoringMath`. - - -#### [NEW] Multiple `streams` can be active at the same time with the same parameters in `StakingHandler.sol `[NOTDONE] - -##### Description -In the contract [StakingHandler]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L103-L111) it is possible to add and activate `streams` with the same parameters. This can lead to duplicate `streams` with the same parameters executed by mistake. - - -##### Recommendation - -We recommend adding checks that `stream` is added before submitting a new one. - - -#### [NEW] There is no limit for the amount of schedules on streams in `StakingHandlers`[NOTDONE] - -##### Description - -There is no limit for the amount of schedules on streams in the contract [`StakingHandlers`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L103-L111). This can cause the block gas limit to be exceeded. - -##### Recommendation -We recommend limiting values of `scheduleTimes` or `scheduleRewards`.[NOTDONE] - - -#### [NEW] It is possible to remove tokens that are used by another contract in `VaultPackage`[DONE] - -##### Description -Calling the [`removeSupportedToken`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L47-L51) function in the `VaultPackage` contract removes tokens which are used in the `StakingHandler` contract to pay rewards and staked tokens. - -##### Recommendation - -We recommend adding logic to check that tokens are not used in any other contract before removing them. - -### INFO - - -#### [NEW] There's no logging of reverted transactions in `MultiSigWallet`[DONE] -##### Description -In the function [`executeConfirmation`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L144) there's no logging of failed transactions. -```solidity -(bool success, ) = transaction.to.call{ value: transaction.value }(transaction.data); -require(success, "tx failed"); -``` - -##### Recommendation -We recommend replace this construction for the next one: -```solidity -error TransactionRevered(bytes data); -... -(bool success, bytes data) = transaction.to.call{ value: transaction.value }(transaction.data); - -if (success) { - emit ExecuteTransaction(msg.sender, _txIndex); -} else { - revert TransactionRevered(data); -} -``` -This will allow monitoring of suspicious activity that involves using of `MultiSigWallet`. - - -#### [NEW] Non-optimal packing of the `Transaction` structure in `MultiSigWallet`[DONE] -##### Description - -The structure [`Transaction`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L9) uses a non-optimized storage layout. - -##### Recommendation -We recommend optimizing storage layout the following way: - -```solidity -struct Transaction { - address to; - bool executed; - bytes data; - uint value; - uint numConfirmations; -} -``` - -#### [NEW] Incorrect status check in `execute` function in `Governor`[DONE] -##### Description -In the [`execute`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol#L76) function there is an incorrect check of `Proposal` status: -```solidity -require(status == ProposalState.Succeeded || status == ProposalState.Queued, "Governor: proposal not successful"); -``` -In the [MainTokenGovernor.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/MainTokenGovernor.sol) contract, that inherits from `Governor`, the execution is passed to the `TimelockController` contract. For a transaction to be executed through `TimelockController` it must only have the `ProposalState.Queued` status. Otherwise the gas will be wasted and the `execute` call will be reverted. -##### Recommendation -We recommend changing the status check for `Proposal`: -```solidity -require(status == ProposalState.Queued, "Governor: proposal not successful"); -``` - -#### [NEW] `_minDelay` can be set to zero in `TimelockController`[NOTDONE] -##### Description -In the `TimelockController` contract the `_minDelay` parameter can be set to `0` during [initialization](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L67) and in the [`updateDelay`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L149) function. This will result in batch being able to be executed in the same block it was queued for execution. - -##### Recommendation -We recommend adding a check that `_minDelay != 0`. - -#### [NEW] There is a redundant `initialized` check in `VMainToken`[DONE] -##### Description -```solidity -require(!initialized, "already init"); -initialized = true; -``` -The [`initToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L24) function contains redundant code with checking and setting the value of the `initialized` parameter, since this check already exists in the `initializer` modifier in the `initToken` function. -##### Recommendation -We recommend deleting these lines. - - -#### [NEW] There is redundant code in the `VMainToken` contract[NOTDONE for future] -##### Description -The [`_mint`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L74) and [`_burn`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L78) functions in the `VMainToken.sol` contract are redundant and essentially do not overload the parent functions. -##### Recommendation -We recommend deleting these functions. - -#### [NEW] The `Governor` and `TimeLockController` do not support the `ERC721` and `ERC1155` tokens[DOESNT REQUIRE] -##### Description -The [`Governor`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/Governor.sol) and [`TimelockController`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol) contracts lack the following methods: - -```solidity -/** - * @dev See {IERC721Receiver-onERC721Received}. - */ -function onERC721Received( - address, - address, - uint256, - bytes memory -) public virtual override returns (bytes4) { - return this.onERC721Received.selector; -} - -/** - * @dev See {IERC1155Receiver-onERC1155Received}. - */ -function onERC1155Received( - address, - address, - uint256, - uint256, - bytes memory -) public virtual override returns (bytes4) { - return this.onERC1155Received.selector; -} - -/** - * @dev See {IERC1155Receiver-onERC1155BatchReceived}. - */ -function onERC1155BatchReceived( - address, - address, - uint256[] memory, - uint256[] memory, - bytes memory -) public virtual override returns (bytes4) { - return this.onERC1155BatchReceived.selector; -} -``` - -Thus `Governor` and `TimeLockController` do not support tokens with `ERC721` and `ERC1155` standards. -##### Recommendation -We recommend implementing these functions if the `Governor` and `TimeLockController` contracts require support for the `ERC721` and `ERC1155` tokens. And also create a list of trusted tokens that can work with (see above - `ERC20` standard tokens transfer possibility). - -#### [NEW] The `addSupportedToken` and `removeSupportedToken` calls have an redundant `pausable` modifier in the `VaultPackage` contract[DONE] -##### Description -In the `VaultPackage` contract the calls [`addSupportedToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L41) and [`removeSupportedToken`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L47) have a redundant modifier `pausable` since the calls are only possible from the `DEFAULT_ADMIN_ROLE` address and the modifier `pausable` contains the following condition -```solidity -require((paused & flag) == 0 || hasRole(DEFAULT_ADMIN_ROLE, msg.sender), "paused contract"); -``` -where the `paused` condition will be ignored. - -##### Recommendation -We recommend reconsidering the `addSupportedToken` and `removeSupportedToken` function modifiers or removing the `pausable` modifier. - -#### [NEW] There are no checks that `admin`, `proposers` and `executors` are not zero addresses in `TimelockController`[NOTDONE] - -##### Description - -In the contract [`TimelockController`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/governance/TimelockController.sol#L49-L69) constructor there are no checks that `admin`, `proposers` and `executors` are not zero addresses. - -##### Recommendation - -We recommend adding checks that `admin`, `proposers` and `executors` are not zero addresses. - -#### [NEW] Unused import of `StakingStructs` in `StakingStorage` - -##### Description - -[Import of `StakingStructs`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/StakingStorage.sol#L7) in the `StakingStorage`contract is never used. - - -##### Recommendation - -We recommend removing it to keep the codebase clean. - -#### [NEW] Unused constant `ONE_MONTH` in `StakingGettersHelper`[DONE] - -##### Description - -The [`ONE_MONTH`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/helpers/StakingGettersHelper.sol#L13) constant in the `StakingGettersHelper` contract is never used. - -##### Recommendation -We recommend removing it to keep the codebase clean. - - -#### [NEW] Non-optimal storage layout for `Stream` struct in `StakingStructs`[DONE] - -##### Description - -[`Stream` struct](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/StakingStructs.sol#L54-L66) in the `StakingStructs` contract has non-optimal storage layout. - -##### Recommendation -We recommend moving `StreamStatus` definition after the `rewardToken` line in the struct `Stream` in order to store values in one slot. -```solidity -struct Stream { - address owner; // stream owned by the ERC-20 reward token owner - address manager; // stream manager handled by Main stream manager role - address rewardToken; - StreamStatus status; - uint256 rewardDepositAmount; // the reward amount that has been deposited by a third party - uint256 rewardClaimedAmount; /// how much rewards have been claimed by stakers - uint256 maxDepositAmount; // maximum amount of deposit - uint256 minDepositAmount; // minimum amount of deposit - uint256 tau; // pending time prior reward release - uint256 rps; // Reward per share for a stream j>0 - Schedule schedule; -} -``` - -#### [NEW] Unnecessary `'` in a `RewardsLibrary` comment[DONE] - -##### Description -There is an explicit `'` in the comment in [`RewardsLibrary.sol#L82`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L82) line. - -##### Recommendation -We recommend removing `'` from the comment. - - -#### [NEW] There is a typo in a comment in `StakingInternals`[DONE] - -##### Description - -There is a typo in the word "have" in the following line [`StakingInternals.sol#L95`]( -https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingInternals.sol#L95). - -```solidity -// user does not hae enough voteToken, it is still able to burn and unlock -``` - -##### Recommendation -We recommend changing it to: -```solidity -// user does not have enough voteToken, it is still able to burn and unlock -``` - -#### [NEW] Redundant check for `maxDepositAmount > 0` in `RewardsCalculator`[DONE] - -##### Description - -There is a redundant check for `maxDepositAmount > 0` in the next lines: - -- [RewardsCalculator.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L21-L23) -- [RewardsLibrary.sol](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/library/RewardsLibrary.sol#L21-L23) - -Since `minDepositAmount` is already greater than `0` and `maxDepositAmount` must be bigger than `minDepositAmount` there is no need to check that `maxDepositAmount > 0`. - -##### Recommendation - -We recommend removing requirement of `maxDepositAmount > 0` for gas savings and improving code readability. - - -#### [NEW] It is not possible to withdraw tokens that were sent by mistake[NOTDONE, no tokens are sent there] - -##### Description - -It is not possible to withdraw tokens that were sent by mistake it the following contracts: - -- [`RewardsCalculator.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol) -- [`StakingPackage.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingPackage.sol) -- [`VMainToken.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol) -- [`MainToken.sol`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/MainToken.sol) - -##### Recommendation - -We recommend adding `sweep` function to withdraw tokens that were sent by mistake. - - -#### [NEW] Unused import of `ReentracyGuard` in `StakingHandlers`[DONE] -##### Description -There is import of [`ReentracyGuard`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L11) in the `StakingHandlers` contract but `nonReentrant` from this class is never used in `StakingHandlers`. - -##### Recommendation -We recommend removing the unused import. - -#### [NEW] Сustom `initializer` modifier is used instead of one from OpenZeppelin[DONE] - -##### Description - -It is better to use [Openzeppelin `initializer` ](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/proxy/utils/Initializable.sol#L83) instead of custom modifiers in the next functions: - -- [`StakingHandler.sol#L33`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) -- [`VaultPackage.sol#L18`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/vault/packages/VaultPackage.sol#L18) -- [`VMainToken.sol#L24`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L24) - -##### Recommendation - -We recommend using `initializer` and `initializable` modifiers from Openzeppelin instead of implementing custom modifiers. - - -#### [NEW] Stream manager, treasury manager and admin represent the same account in `StakingHandlers`[NTDONE] - -##### Description - -In the [`initializeStaking`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L33) function in the `StakingHandlers` contract multiple roles are assigned to the same `admin` address. - -##### Recommendation -We recommend to transfer treasury role after the deployment and the staking setting. Admin and manager of the initial `stream` should be two different roles. - - -#### [NEW] Revert message strings are too long[NTDONE] - -##### Description - -- [`VMainToken.sol#L65-L68`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/tokens/VMainToken.sol#L65-L68) -- [`MultiSigWallet#L30`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L30) -- [`MultiSigWallet.sol#L55`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L55) -- [`MultiSigWallet.sol#L77`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L77) - -After the revert message string is split into 32-byte sized chunks and stored in `memory` using `mstore`, the `memory` offsets are given to `revert(offset, length)`. For chunks shorter than 32 bytes, and for low `--optimize-runs` values (usually even the default value of `200`), instead of using `push32(val)` (where `val` is the 32 byte hexadecimal representation of the string with zero padding on the least significant bits) the Solidity compiler replaces it by `shl(value, short-value)`, where `short-value` does not have any zero padding. This saves the total amount of bytes in the deploy code and therefore saves deploy time cost, at the expense of extra 6 gas consumption during runtime. -This means that shorter revert strings saves deploy time costs of the contract. Note that this is not relevant for high values of `--optimize-runs` since `push32` value will not be replaced by a `shl(value, short-value)` equivalent by the Solidity compiler. - -Going back, each 32 byte chunk of the string requires an extra `mstore`. That is, additional cost for `mstore`, `memory` expansion costs, as well as stack operations. Note that this runtime cost is only relevant when the revert condition is met. - -Overall, shorter revert strings can save deploy time as well as runtime costs. - -##### Recommendation - -We recommend making revert strings shorter. -Note that if your contracts already allow Solidity `0.8.4` and above, then consider using [custom errors](https://blog.soliditylang.org/2021/04/21/custom-errors). They provide more gas efficiency and also allow developers to describe the errors in detail using [NatSpec](https://docs.soliditylang.org/en/latest/natspec-format.html). The main disadvantage of this approach is that some tooling may not have proper support for it yet. - - -#### [NEW] Unnecessary reads from storage[DONE for applicable] - -##### Description - -In the next lines using `MLOAD` and `MSTORE` to cache the variable in `memory` saves more gas than `SLOAD`, since they use only 3 gas, instead of the initial 100: - -- [`MultiSigWallet.sol#L138`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/treasury/MultiSigWallet.sol#L138) -- [`StakingHandler.sol#L191`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L191) -- [`StakingHandler.sol#L200`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L200) -- [`StakingHandler.sol#L210`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L210) -- [`StakingHandler.sol#L237`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L237) -- [`StakingHandler.sol#L244`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/StakingHandler.sol#L244) - - -##### Recommendation - -We recommend caching this storage variable in `memory` to reduce unnecessary reads from storage and save more gas. - - -#### [NEW] Misleading check `(scheduleTimeLength > 0)` in the `RewardsCalculator`[DONE] - -##### Description - -In the function [`_getStartEndScheduleIndex`](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L94) in the contract `RewardsCalculator` there is the following condition: -```solidity -require(scheduleTimeLength > 0, "bad schedules"); -``` - -This condition allows `scheduleTimeLength` value to be set to 1. This can lead to [underflow](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L105) and [incorrect operation of cycles](https://github.com/Into-the-Fathom/fathom-dao-smart-contracts/blob/5e9f3a23bd2b6deb9babe1a3ad984fd84cf51b7a/contracts/dao/staking/packages/RewardsCalculator.sol#L98) further down the code. - -##### Recommendation - -We recommend changing it to -```solidity -require(scheduleTimeLength >= 2, "bad schedules"); -``` -or completely remove this check, since this condition is already checked in `validateStreamParameters()` when the stream is created. - -## Conclusion - -The following table contains the total number of issues that were found during audit: - -[FINDINGS] - -Current audit revealed 75 issues of varying degrees of importance. For each founded issue the Contractor's team made recommendations on effective solving. \ No newline at end of file diff --git a/coralX-scenarios.js b/coralX-scenarios.js index 3957522..fbe91b3 100644 --- a/coralX-scenarios.js +++ b/coralX-scenarios.js @@ -21,14 +21,22 @@ module.exports = { ['execute', '--path', 'scripts/migrations/prod', '--network', 'xdc'], ['execute', '--path', 'scripts/migrations/save-address/3_save_address_prod.js', '--network', 'xdc'] ], + + transferTokenFromMultisigApothem: [ + ['compile'], + ['execute', '--path', 'scripts/units/transfer-tokens.js', '--network', 'apothem'], + ], + + addOwnersToMultisigApothem: [ + ['compile'], + ['execute', '--path', 'scripts/units/setup-multisig-owners.js', '--network', 'apothem'], + ], + migrateAndConfigureForTests: [ ['compile'], ['execute', '--path', 'scripts/migrations/test-deployment'], - ['execute', '--path', 'scripts/migrations/save-address/1_save_address_deployment.js'], ['execute', '--path', 'scripts/migrations/setup'], - ['execute', '--path', 'scripts/migrations/save-address/2_save_address_setup.js'], ['execute', '--path', 'scripts/migrations/test'], - ['execute', '--path', 'scripts/migrations/save-address/3_save_address_prod.js'], ['execute', '--path', 'scripts/migrations/upgrades'], ], createStablecoinPool: [ diff --git a/deprecated/scripts/2_init_staking.js b/deprecated/scripts/2_init_staking.js deleted file mode 100644 index 8aa3d72..0000000 --- a/deprecated/scripts/2_init_staking.js +++ /dev/null @@ -1,125 +0,0 @@ -const blockchain = require("../../tests/helpers/blockchain"); - -const VMainToken = artifacts.require('./dao/tokens/VMainToken.sol'); - -const IStaking = artifacts.require('./dao/staking/interfaces/IStaking.sol'); -const StakingPackage = artifacts.require('./dao/staking/packages/StakingPackage.sol'); - -const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); - -const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); - -const Vault = artifacts.require('./dao/staking/vault/packages/VaultPackage.sol'); - -const RewardsCalculator = artifacts.require('./dao/staking/packages/RewardsCalculator.sol'); - -const _createWeightObject = ( - maxWeightShares, - minWeightShares, - maxWeightPenalty, - minWeightPenalty, - weightMultiplier) => { - return { - maxWeightShares: maxWeightShares, - minWeightShares: minWeightShares, - maxWeightPenalty: maxWeightPenalty, - minWeightPenalty: minWeightPenalty, - penaltyWeightMultiplier: weightMultiplier - } -} - -const _createVoteWeights = ( - voteShareCoef, - voteLockCoef) => { - return { - voteShareCoef: voteShareCoef, - voteLockCoef: voteLockCoef - } -} - -const _getTimeStamp = async () => { - const timestamp = await blockchain.getLatestBlockTimestamp(); - return timestamp; -} - -const vMainTokenCoefficient = 500; - -const oneYear = 31556926; - -const maxWeightShares = 1024; -const minWeightShares = 256; -const maxWeightPenalty = 3000; -const minWeightPenalty = 100; -const weightMultiplier = 10; -const maxNumberOfLocks = 10; - -const tau = 2; - -const lockingVoteWeight = 365 * 24 * 60 * 60; - -module.exports = async function(deployer) { - const stakingService = await IStaking.at(StakingPackage.address); - - const weightObject = _createWeightObject( - maxWeightShares, - minWeightShares, - maxWeightPenalty, - minWeightPenalty, - weightMultiplier - ); - - const startTime = await _getTimeStamp() + 3 * 24 * 24 * 60; - - const scheduleTimes = [ - startTime, - startTime + oneYear, - startTime + 2 * oneYear, - startTime + 3 * oneYear, - startTime + 4 * oneYear, - ]; - - const scheduleRewards = [ - web3.utils.toWei('2000', 'ether'), - web3.utils.toWei('1000', 'ether'), - web3.utils.toWei('500', 'ether'), - web3.utils.toWei('250', 'ether'), - web3.utils.toWei("0", 'ether') - ]; - - const voteObject = _createVoteWeights( - vMainTokenCoefficient, - lockingVoteWeight - ); - - await stakingService.initializeStaking( - MultiSigWallet.address, - Vault.address, - MainToken.address, - VMainToken.address, - weightObject, - scheduleTimes, - scheduleRewards, - tau, - voteObject, - maxNumberOfLocks, - RewardsCalculator.address, - {gas: 8000000} - ); - - console.log("....") - - await stakingService.initializeStaking( - MultiSigWallet.address, - Vault.address, - MainToken.address, - VMainToken.address, - weightObject, - scheduleTimes, - scheduleRewards, - tau, - voteObject, - maxNumberOfLocks, - RewardsCalculator.address, - {gas: 8000000} - ); -} \ No newline at end of file diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index 80657c7..c628ff9 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -45,7 +45,7 @@ const maxWeightPenalty = 3000; const minWeightPenalty = 100; const weightMultiplier = 10; const maxNumberOfLocks = 10; -const minimumLockingPeriod = 4 * 86400; +const minimumLockingPeriod = 14 * 86400; const lockingVoteWeight = 31556926; diff --git a/scripts/migrations/prod/5_init_main_stream.js b/scripts/migrations/prod/5_init_main_stream.js index eb191d1..315810f 100644 --- a/scripts/migrations/prod/5_init_main_stream.js +++ b/scripts/migrations/prod/5_init_main_stream.js @@ -8,7 +8,6 @@ const EMPTY_BYTES = '0x000000000000000000000000000000000000000000000000000000000 const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') -const ExecuteTransactionSuccess = "ExecuteTransaction(address,uint256)" const _encodeApproveFunction = (_account, _amount) => { let toRet = web3.eth.abi.encodeFunctionCall({ name: 'approve', @@ -90,5 +89,5 @@ module.exports = async function(deployer) { let txIndexInit = eventsHelper.getIndexedEventArgs(resultInit, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexInit, {gas: 8000000}); - const resultOfInitMainStream = await multiSigWallet.executeTransaction(txIndexInit, {gas: 10000000}); + await multiSigWallet.executeTransaction(txIndexInit, {gas: 10000000}); } diff --git a/scripts/migrations/prod/6_setup_council_stakes.js b/scripts/migrations/prod/6_setup_council_stakes.js index 0f07fb4..8e0fda5 100644 --- a/scripts/migrations/prod/6_setup_council_stakes.js +++ b/scripts/migrations/prod/6_setup_council_stakes.js @@ -11,7 +11,7 @@ const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWa const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const LOCK_PERIOD = 4 * 24 * 60 * 60; +const LOCK_PERIOD = 365 * 24 * 60 * 60; const T_TO_TRANSFER = web3.utils.toWei('30000000', 'ether'); const T_TO_STAKE = web3.utils.toWei('10000000', 'ether'); diff --git a/scripts/migrations/prod/8_staking_getter_helpers.js b/scripts/migrations/prod/7_staking_getter_helpers.js similarity index 100% rename from scripts/migrations/prod/8_staking_getter_helpers.js rename to scripts/migrations/prod/7_staking_getter_helpers.js diff --git a/scripts/migrations/save-address/1_save_address_deployment.js b/scripts/migrations/save-address/1_save_address_deployment.js index ba48ad9..ada3e27 100644 --- a/scripts/migrations/save-address/1_save_address_deployment.js +++ b/scripts/migrations/save-address/1_save_address_deployment.js @@ -20,7 +20,7 @@ module.exports = async function(deployer) { } let data = JSON.stringify(addresses); - fs.writeFileSync('./build/build_system_addresses.json',data, function(err){ + fs.writeFileSync('./addresses.json',data, function(err){ if(err){ console.log(err) } diff --git a/scripts/migrations/save-address/2_save_address_setup.js b/scripts/migrations/save-address/2_save_address_setup.js index 5ae96b3..8ceefca 100644 --- a/scripts/migrations/save-address/2_save_address_setup.js +++ b/scripts/migrations/save-address/2_save_address_setup.js @@ -1,7 +1,7 @@ const VaultProxyAdmin = artifacts.require('./common/proxy/VaultProxyAdmin.sol'); const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') const fs = require('fs') -const rawdata = fs.readFileSync('../../../build/build_system_addresses.json'); +const rawdata = fs.readFileSync('../../../addresses.json'); let daoAddress = JSON.parse(rawdata) module.exports = async function(deployer) { let addresses = { @@ -16,7 +16,7 @@ module.exports = async function(deployer) { let data = JSON.stringify(newAddresses); - fs.writeFileSync('./build/build_system_addresses.json',data, function(err){ + fs.writeFileSync('./addresses.json',data, function(err){ if(err){ console.log(err) } diff --git a/scripts/migrations/save-address/3_save_address_prod.js b/scripts/migrations/save-address/3_save_address_prod.js index 51d604a..4784a14 100644 --- a/scripts/migrations/save-address/3_save_address_prod.js +++ b/scripts/migrations/save-address/3_save_address_prod.js @@ -2,7 +2,7 @@ const StakingProxyAdmin = artifacts.require('./common/proxy/StakingProxyAdmin.so const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') const StakingGettersHelper = artifacts.require('./dao/staking/helpers/StakingGettersHelper.sol') const fs = require('fs') -const rawdata = fs.readFileSync('../../../build/build_system_addresses.json'); +const rawdata = fs.readFileSync('../../../addresses.json'); let daoAddress = JSON.parse(rawdata) module.exports = async function(deployer) { let addresses = { @@ -18,7 +18,7 @@ module.exports = async function(deployer) { let data = JSON.stringify(newAddresses); - fs.writeFileSync('./build/build_system_addresses.json',data, function(err){ + fs.writeFileSync('./addresses.json',data, function(err){ if(err){ console.log(err) } diff --git a/scripts/migrations/setup/1_init_timelock_controller.js b/scripts/migrations/setup/1_init_timelock_controller.js index 61ec73a..9d1ec5e 100644 --- a/scripts/migrations/setup/1_init_timelock_controller.js +++ b/scripts/migrations/setup/1_init_timelock_controller.js @@ -8,7 +8,7 @@ const ITimelockController = artifacts.require('./dao/governance/interfaces/ITime // A Scheduled operation is an operation that becomes valid after a given delay. // Once the delay time has passed, the operation can be performed. Each schedules delay must be at least minDelay. // minDelay is set in the initialize function call, and can be updated using function updateDelay. -const minDelay = 30; //?? What should be initialized? +const minDelay = 86400 const proposers = [MainTokenGovernor.address]; const executors = [MainTokenGovernor.address]; diff --git a/scripts/migrations/prod/7_setup_multisig.js b/scripts/units/setup-multisig-owners.js similarity index 61% rename from scripts/migrations/prod/7_setup_multisig.js rename to scripts/units/setup-multisig-owners.js index fc2373e..c093a2c 100644 --- a/scripts/migrations/prod/7_setup_multisig.js +++ b/scripts/units/setup-multisig-owners.js @@ -1,16 +1,20 @@ -const eventsHelper = require("../../tests/helpers/eventsHelper"); +const fs = require('fs'); + +const eventsHelper = require("../tests/helpers/eventsHelper"); -const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const COUNCIL_1 = "0xc0Ee98ac1a44B56fbe2669A3B3C006DEB6fDd0f9"; -const COUNCIL_2 = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; - +const COUNCIL_1_PLACEHOLDER = "0xc0Ee98ac1a44B56fbe2669A3B3C006DEB6fDd0f9"; +const COUNCIL_2_PLACEHOLDER = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; +const rawdata = fs.readFileSync('../../addresses.json'); +const addresses = JSON.parse(rawdata); const _encodeAddOwnersFunction = (_accounts) => { + + let toRet = web3.eth.abi.encodeFunctionCall({ name: 'addOwners', type: 'function', @@ -24,12 +28,13 @@ const _encodeAddOwnersFunction = (_accounts) => { } module.exports = async function(deployer) { - const multiSigWallet = await IMultiSigWallet.at(MultiSigWallet.address); + const MULTISIG_WALLET_ADDRESS = addresses.multiSigWallet; + const multiSigWallet = await IMultiSigWallet.at(MULTISIG_WALLET_ADDRESS); let result = await multiSigWallet.submitTransaction( - multiSigWallet.address, + MULTISIG_WALLET_ADDRESS, EMPTY_BYTES, - _encodeAddOwnersFunction([COUNCIL_1, COUNCIL_2]), + _encodeAddOwnersFunction([COUNCIL_1_PLACEHOLDER, COUNCIL_2_PLACEHOLDER]), 0, {gas: 8000000} ); diff --git a/scripts/units/transfer-tokens-three-signature.js b/scripts/units/transfer-tokens-three-signature.js deleted file mode 100644 index e69de29..0000000 diff --git a/scripts/units/transfer-tokens-one-signature.js b/scripts/units/transfer-tokens.js similarity index 70% rename from scripts/units/transfer-tokens-one-signature.js rename to scripts/units/transfer-tokens.js index ca5fae5..10755d5 100644 --- a/scripts/units/transfer-tokens-one-signature.js +++ b/scripts/units/transfer-tokens.js @@ -1,15 +1,15 @@ -const eventsHelper = require("../../tests/helpers/eventsHelper"); +const fs = require('fs'); + +const eventsHelper = require("../tests/helpers/eventsHelper"); const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const T_TO_TRANSFER_PLACEHOLDER = web3.utils.toWei('','ether') //SET AS NEEDED -const TRANSFER_TO_ACCOUNT_PLACEHOLDER = "" //SET AS NEEDED -const MULTISIG_WALLET_ADDRESS = "" //CONSTANT -const MAIN_TOKEN_ADDRESS = "" //CONSTANT +const rawdata = fs.readFileSync('../../addresses.json'); +const addresses = JSON.parse(rawdata); const _encodeTransferFunction = (_account, t_to_stake) => { let toRet = web3.eth.abi.encodeFunctionCall({ @@ -30,11 +30,16 @@ const _encodeTransferFunction = (_account, t_to_stake) => { module.exports = async function(deployer) { + const T_TO_TRANSFER_PLACEHOLDER = web3.utils.toWei('10000000','ether') //SET AS NEEDED + const TRANSFER_TO_ACCOUNT_PLACEHOLDER = "0x4C5F0f90a2D4b518aFba11E22AC9b8F6B031d204" //SET AS NEEDED + const MULTISIG_WALLET_ADDRESS = addresses.multiSigWallet; + const FATHOM_TOKEN_ADDRESS = addresses.fthmToken; + const multiSigWallet = await IMultiSigWallet.at(MULTISIG_WALLET_ADDRESS) const _transferFromMultiSigTreasury = async (_account, _value) => { const result = await multiSigWallet.submitTransaction( - MAIN_TOKEN_ADDRESS, + FATHOM_TOKEN_ADDRESS, EMPTY_BYTES, _encodeTransferFunction(_account, _value), 0, @@ -45,5 +50,5 @@ module.exports = async function(deployer) { await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); } - await _transferFromMultiSigTreasury(TRANSFER_TO_ACCOUNT_PLACEHOLDER,T_TO_TRANSFER); + await _transferFromMultiSigTreasury(TRANSFER_TO_ACCOUNT_PLACEHOLDER,T_TO_TRANSFER_PLACEHOLDER); } \ No newline at end of file From 55c9a58effcc7b18b58636412c3b348f828ddc0a Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 15 Feb 2023 09:10:24 +0545 Subject: [PATCH 71/77] sending token to an address --- .../prod/8_send_main_token_to_address.js | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 scripts/migrations/prod/8_send_main_token_to_address.js diff --git a/scripts/migrations/prod/8_send_main_token_to_address.js b/scripts/migrations/prod/8_send_main_token_to_address.js new file mode 100644 index 0000000..fb043f6 --- /dev/null +++ b/scripts/migrations/prod/8_send_main_token_to_address.js @@ -0,0 +1,49 @@ + +const eventsHelper = require("../../tests/helpers/eventsHelper"); +const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); + +const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); +const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); + +const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; +const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; +const T_TO_TRANSFER_PLACEHOLDER = web3.utils.toWei('10000000','ether') //SET AS NEEDED +const TRANSFER_TO_ACCOUNT_PLACEHOLDER = "0x4C5F0f90a2D4b518aFba11E22AC9b8F6B031d204" //SET AS NEEDED + +const _encodeTransferFunction = (_account, t_to_stake) => { + + let toRet = web3.eth.abi.encodeFunctionCall({ + name: 'transfer', + type: 'function', + inputs: [{ + type: 'address', + name: 'to' + },{ + type: 'uint256', + name: 'amount' + }] + }, [_account, t_to_stake]); + + return toRet; +} + + +module.exports = async function(deployer) { + + const multiSigWallet = await IMultiSigWallet.at(MultiSigWallet.address) + + const _transferFromMultiSigTreasury = async (_account, _value) => { + const result = await multiSigWallet.submitTransaction( + MainToken.address, + EMPTY_BYTES, + _encodeTransferFunction(_account, _value), + 0, + {gas: 8000000} + ); + txIndex = eventsHelper.getIndexedEventArgs(result, SUBMIT_TRANSACTION_EVENT)[0]; + await multiSigWallet.confirmTransaction(txIndex, {gas: 8000000}); + await multiSigWallet.executeTransaction(txIndex, {gas: 8000000}); + } + + await _transferFromMultiSigTreasury(TRANSFER_TO_ACCOUNT_PLACEHOLDER,T_TO_TRANSFER_PLACEHOLDER); +} \ No newline at end of file From ccebe192413f02bf0394e2d3004eee90382bde76 Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 15 Feb 2023 12:04:31 +0545 Subject: [PATCH 72/77] fixing test and changing folder --- coralX-scenarios.js | 3 +-- .../1_deploy_vToken.js | 0 .../2_deploy_timelock_controller.js | 0 .../3_deploy_multisig_treasury.js | 0 .../4_deploy_main_token.js | 0 .../5_deploy_governor.js | 0 .../6_deploy_staking.js | 0 .../7_init_timelock_controller.js | 25 ++++++++++++++++++ .../8_deploy_init_vault_proxy.js | 26 +++++++++++++++++++ .../deployment/5_deploy_governor.js | 2 +- 10 files changed, 53 insertions(+), 3 deletions(-) rename scripts/migrations/{test-deployment => deployment-test}/1_deploy_vToken.js (100%) rename scripts/migrations/{test-deployment => deployment-test}/2_deploy_timelock_controller.js (100%) rename scripts/migrations/{test-deployment => deployment-test}/3_deploy_multisig_treasury.js (100%) rename scripts/migrations/{test-deployment => deployment-test}/4_deploy_main_token.js (100%) rename scripts/migrations/{test-deployment => deployment-test}/5_deploy_governor.js (100%) rename scripts/migrations/{test-deployment => deployment-test}/6_deploy_staking.js (100%) create mode 100644 scripts/migrations/deployment-test/7_init_timelock_controller.js create mode 100644 scripts/migrations/deployment-test/8_deploy_init_vault_proxy.js diff --git a/coralX-scenarios.js b/coralX-scenarios.js index fbe91b3..eb1e9e8 100644 --- a/coralX-scenarios.js +++ b/coralX-scenarios.js @@ -34,8 +34,7 @@ module.exports = { migrateAndConfigureForTests: [ ['compile'], - ['execute', '--path', 'scripts/migrations/test-deployment'], - ['execute', '--path', 'scripts/migrations/setup'], + ['execute', '--path', 'scripts/migrations/deployment-test'], ['execute', '--path', 'scripts/migrations/test'], ['execute', '--path', 'scripts/migrations/upgrades'], ], diff --git a/scripts/migrations/test-deployment/1_deploy_vToken.js b/scripts/migrations/deployment-test/1_deploy_vToken.js similarity index 100% rename from scripts/migrations/test-deployment/1_deploy_vToken.js rename to scripts/migrations/deployment-test/1_deploy_vToken.js diff --git a/scripts/migrations/test-deployment/2_deploy_timelock_controller.js b/scripts/migrations/deployment-test/2_deploy_timelock_controller.js similarity index 100% rename from scripts/migrations/test-deployment/2_deploy_timelock_controller.js rename to scripts/migrations/deployment-test/2_deploy_timelock_controller.js diff --git a/scripts/migrations/test-deployment/3_deploy_multisig_treasury.js b/scripts/migrations/deployment-test/3_deploy_multisig_treasury.js similarity index 100% rename from scripts/migrations/test-deployment/3_deploy_multisig_treasury.js rename to scripts/migrations/deployment-test/3_deploy_multisig_treasury.js diff --git a/scripts/migrations/test-deployment/4_deploy_main_token.js b/scripts/migrations/deployment-test/4_deploy_main_token.js similarity index 100% rename from scripts/migrations/test-deployment/4_deploy_main_token.js rename to scripts/migrations/deployment-test/4_deploy_main_token.js diff --git a/scripts/migrations/test-deployment/5_deploy_governor.js b/scripts/migrations/deployment-test/5_deploy_governor.js similarity index 100% rename from scripts/migrations/test-deployment/5_deploy_governor.js rename to scripts/migrations/deployment-test/5_deploy_governor.js diff --git a/scripts/migrations/test-deployment/6_deploy_staking.js b/scripts/migrations/deployment-test/6_deploy_staking.js similarity index 100% rename from scripts/migrations/test-deployment/6_deploy_staking.js rename to scripts/migrations/deployment-test/6_deploy_staking.js diff --git a/scripts/migrations/deployment-test/7_init_timelock_controller.js b/scripts/migrations/deployment-test/7_init_timelock_controller.js new file mode 100644 index 0000000..93853ae --- /dev/null +++ b/scripts/migrations/deployment-test/7_init_timelock_controller.js @@ -0,0 +1,25 @@ +// components +const TimelockController = artifacts.require('./dao/governance/TimelockController.sol'); +const MainTokenGovernor = artifacts.require('./dao/governance/MainTokenGovernor.sol'); +const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); + +// interfaces +const ITimelockController = artifacts.require('./dao/governance/interfaces/ITimelockController.sol'); +// A Scheduled operation is an operation that becomes valid after a given delay. +// Once the delay time has passed, the operation can be performed. Each schedules delay must be at least minDelay. +// minDelay is set in the initialize function call, and can be updated using function updateDelay. +const minDelay = 30 +const proposers = [MainTokenGovernor.address]; +const executors = [MainTokenGovernor.address]; + +module.exports = async function(deployer) { + const timelockController = await ITimelockController.at(TimelockController.address); + + await timelockController.initialize( + minDelay, + MultiSigWallet.address, + proposers, + executors, + { gas: 120000000 } + ); +}; diff --git a/scripts/migrations/deployment-test/8_deploy_init_vault_proxy.js b/scripts/migrations/deployment-test/8_deploy_init_vault_proxy.js new file mode 100644 index 0000000..76ee9d1 --- /dev/null +++ b/scripts/migrations/deployment-test/8_deploy_init_vault_proxy.js @@ -0,0 +1,26 @@ +const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); +const VaultProxyAdmin = artifacts.require('./common/proxy/VaultProxyAdmin.sol'); +const VaultProxy = artifacts.require('./common/proxy/VaultProxy.sol') +const Vault = artifacts.require('./dao/staking/vault/packages/VaultPackage.sol'); +const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); + + +module.exports = async function(deployer) { + + let toInitialize = web3.eth.abi.encodeFunctionCall({ + name: 'initVault', + type: 'function', + inputs: [{ + type: 'address', + name: '_admin' + }, + { + type: 'address[]', + name: 'supportedTokens' + } + ] + }, [MultiSigWallet.address,[MainToken.address]]); + + await deployer.deploy(VaultProxyAdmin, {gas:8000000}); + await deployer.deploy(VaultProxy, Vault.address, VaultProxyAdmin.address, toInitialize, {gas:8000000}); +} \ No newline at end of file diff --git a/scripts/migrations/deployment/5_deploy_governor.js b/scripts/migrations/deployment/5_deploy_governor.js index 2897056..76c39d7 100644 --- a/scripts/migrations/deployment/5_deploy_governor.js +++ b/scripts/migrations/deployment/5_deploy_governor.js @@ -7,7 +7,7 @@ const VMainToken_address = VMainToken.address; const TimelockController_address = TimelockController.address; const MultiSigWallet_address = MultiSigWallet.address; const initialVotingDelay = 86400; //Approx. 2 days with one block every 2s -const votingPeriod = 216000; // (5 * 24 * 60 * 60) / 2, approx. 5 days with one block every 2s +const votingPeriod = 216000; // approx. 5 days with one block every 2s -- (5 * 24 * 60 * 60) / 2, const initialProposalThreshold = 1000; // time delay is in timestamp not block. // Each user cannot make proposals if they have recently made a proposal, for a given time delay. From 7693c86ef529ee3c7ee3d038fc15e4ed9b1ebc09 Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 15 Feb 2023 12:38:32 +0545 Subject: [PATCH 73/77] council stakes in new script --- coralX-scenarios.js | 5 +++ ...helpers.js => 6_staking_getter_helpers.js} | 0 ...ess.js => 7_send_main_token_to_address.js} | 0 .../setup_council_stakes.js} | 31 ++++++++++++------- scripts/units/transfer-tokens.js | 7 ++--- 5 files changed, 27 insertions(+), 16 deletions(-) rename scripts/migrations/prod/{7_staking_getter_helpers.js => 6_staking_getter_helpers.js} (100%) rename scripts/migrations/prod/{8_send_main_token_to_address.js => 7_send_main_token_to_address.js} (100%) rename scripts/{migrations/prod/6_setup_council_stakes.js => units/setup_council_stakes.js} (75%) diff --git a/coralX-scenarios.js b/coralX-scenarios.js index eb1e9e8..5a9f832 100644 --- a/coralX-scenarios.js +++ b/coralX-scenarios.js @@ -31,6 +31,11 @@ module.exports = { ['compile'], ['execute', '--path', 'scripts/units/setup-multisig-owners.js', '--network', 'apothem'], ], + + addCouncilStakesApothem: [ + ['compile'], + ['execute', '--path', 'scripts/units/setup_council_stakes.js', '--network', 'apothem'], + ], migrateAndConfigureForTests: [ ['compile'], diff --git a/scripts/migrations/prod/7_staking_getter_helpers.js b/scripts/migrations/prod/6_staking_getter_helpers.js similarity index 100% rename from scripts/migrations/prod/7_staking_getter_helpers.js rename to scripts/migrations/prod/6_staking_getter_helpers.js diff --git a/scripts/migrations/prod/8_send_main_token_to_address.js b/scripts/migrations/prod/7_send_main_token_to_address.js similarity index 100% rename from scripts/migrations/prod/8_send_main_token_to_address.js rename to scripts/migrations/prod/7_send_main_token_to_address.js diff --git a/scripts/migrations/prod/6_setup_council_stakes.js b/scripts/units/setup_council_stakes.js similarity index 75% rename from scripts/migrations/prod/6_setup_council_stakes.js rename to scripts/units/setup_council_stakes.js index 8e0fda5..6192b16 100644 --- a/scripts/migrations/prod/6_setup_council_stakes.js +++ b/scripts/units/setup_council_stakes.js @@ -1,24 +1,30 @@ -const eventsHelper = require("../../tests/helpers/eventsHelper"); +//NOTE: This script can be run only once for each deployment as making COUNCIL_STAKES is only possible once +const fs = require('fs'); + +const eventsHelper = require("../tests/helpers/eventsHelper"); const IStaking = artifacts.require('./dao/staking/interfaces/IStaking.sol'); const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); -const IERC20 = artifacts.require("./dao/tokens/ERC20/IERC20.sol"); -const MultiSigWallet = artifacts.require("./dao/treasury/MultiSigWallet.sol"); const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; const LOCK_PERIOD = 365 * 24 * 60 * 60; - -const T_TO_TRANSFER = web3.utils.toWei('30000000', 'ether'); +//SET AS NEEDED +// this needs to be sum of all the stakes. Right now 10KK * 3. +const T_TOTAL_TO_APPROVE = web3.utils.toWei('30000000', 'ether'); +// this is how much to stake for one council . Right now 10KK const T_TO_STAKE = web3.utils.toWei('10000000', 'ether'); const COUNCIL_1 = "0xc0Ee98ac1a44B56fbe2669A3B3C006DEB6fDd0f9"; const COUNCIL_2 = "0x01d2D3da7a42F64e7Dc6Ae405F169836556adC86"; -const StakingProxy = artifacts.require('./common/proxy/StakingProxy.sol') +const COUNCIL_3 = "0x4C5F0f90a2D4b518aFba11E22AC9b8F6B031d204"; + +const rawdata = fs.readFileSync('../../addresses.json'); +const addresses = JSON.parse(rawdata); const _createLockParamObject = ( _amount, @@ -65,14 +71,13 @@ const _encodeCreateLocksForCouncils = (_createLockParam) => { } module.exports = async function(deployer) { - const stakingService = await IStaking.at(StakingProxy.address); - const multiSigWallet = await IMultiSigWallet.at(MultiSigWallet.address); - const mainToken = await IERC20.at(MainToken.address); + const stakingService = await IStaking.at(addresses.staking); + const multiSigWallet = await IMultiSigWallet.at(addresses.multiSigWallet); let resultApprove = await multiSigWallet.submitTransaction( MainToken.address, EMPTY_BYTES, - _encodeApproveFunction(StakingProxy.address,T_TO_TRANSFER), + _encodeApproveFunction(stakingService.address,T_TOTAL_TO_APPROVE), 0, {gas: 8000000} ) @@ -80,9 +85,9 @@ module.exports = async function(deployer) { let txIndexApprove = eventsHelper.getIndexedEventArgs(resultApprove, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexApprove, {gas: 8000000}); await multiSigWallet.executeTransaction(txIndexApprove, {gas: 8000000}); - + console.log("....Tokens Approved"); const LockParamObjectForAllCouncils = [ - _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,accounts[0]), + _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,COUNCIL_3), _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,COUNCIL_1), _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,COUNCIL_2) ] @@ -94,8 +99,10 @@ module.exports = async function(deployer) { 0, {gas: 8000000} ) + let txIndexCreateLock = eventsHelper.getIndexedEventArgs(resultCreateLock, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexCreateLock, {gas: 8000000}); await multiSigWallet.executeTransaction(txIndexCreateLock, {gas: 8000000}); + console.log("....Council Lock Positions Created"); } \ No newline at end of file diff --git a/scripts/units/transfer-tokens.js b/scripts/units/transfer-tokens.js index 10755d5..2d06bac 100644 --- a/scripts/units/transfer-tokens.js +++ b/scripts/units/transfer-tokens.js @@ -7,6 +7,8 @@ const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWa const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; +const T_TO_TRANSFER_PLACEHOLDER = web3.utils.toWei('10000000','ether') //SET AS NEEDED +const TRANSFER_TO_ACCOUNT_PLACEHOLDER = "0x4C5F0f90a2D4b518aFba11E22AC9b8F6B031d204" //SET AS NEEDED const rawdata = fs.readFileSync('../../addresses.json'); const addresses = JSON.parse(rawdata); @@ -27,11 +29,8 @@ const _encodeTransferFunction = (_account, t_to_stake) => { return toRet; } - - module.exports = async function(deployer) { - const T_TO_TRANSFER_PLACEHOLDER = web3.utils.toWei('10000000','ether') //SET AS NEEDED - const TRANSFER_TO_ACCOUNT_PLACEHOLDER = "0x4C5F0f90a2D4b518aFba11E22AC9b8F6B031d204" //SET AS NEEDED + const MULTISIG_WALLET_ADDRESS = addresses.multiSigWallet; const FATHOM_TOKEN_ADDRESS = addresses.fthmToken; From 2bbf62746afd384a3610e5682600fc01a99f48d8 Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 15 Feb 2023 13:50:07 +0545 Subject: [PATCH 74/77] making comments --- scripts/migrations/prod/7_send_main_token_to_address.js | 5 +++-- scripts/units/setup-multisig-owners.js | 1 + scripts/units/setup_council_stakes.js | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/scripts/migrations/prod/7_send_main_token_to_address.js b/scripts/migrations/prod/7_send_main_token_to_address.js index fb043f6..7e52354 100644 --- a/scripts/migrations/prod/7_send_main_token_to_address.js +++ b/scripts/migrations/prod/7_send_main_token_to_address.js @@ -7,8 +7,7 @@ const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWa const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint256,bytes)"; -const T_TO_TRANSFER_PLACEHOLDER = web3.utils.toWei('10000000','ether') //SET AS NEEDED -const TRANSFER_TO_ACCOUNT_PLACEHOLDER = "0x4C5F0f90a2D4b518aFba11E22AC9b8F6B031d204" //SET AS NEEDED + const _encodeTransferFunction = (_account, t_to_stake) => { @@ -29,6 +28,8 @@ const _encodeTransferFunction = (_account, t_to_stake) => { module.exports = async function(deployer) { + const T_TO_TRANSFER_PLACEHOLDER = web3.utils.toWei('10000000','ether') //SET AS NEEDED + const TRANSFER_TO_ACCOUNT_PLACEHOLDER = accounts[0] //SET AS NEEDED const multiSigWallet = await IMultiSigWallet.at(MultiSigWallet.address) diff --git a/scripts/units/setup-multisig-owners.js b/scripts/units/setup-multisig-owners.js index c093a2c..b3690e9 100644 --- a/scripts/units/setup-multisig-owners.js +++ b/scripts/units/setup-multisig-owners.js @@ -1,3 +1,4 @@ +//NOTE: Do this at the very end as other scripts wont execute after this is done const fs = require('fs'); const eventsHelper = require("../tests/helpers/eventsHelper"); diff --git a/scripts/units/setup_council_stakes.js b/scripts/units/setup_council_stakes.js index 6192b16..f35fb49 100644 --- a/scripts/units/setup_council_stakes.js +++ b/scripts/units/setup_council_stakes.js @@ -14,7 +14,8 @@ const SUBMIT_TRANSACTION_EVENT = "SubmitTransaction(uint256,address,address,uint const LOCK_PERIOD = 365 * 24 * 60 * 60; //SET AS NEEDED -// this needs to be sum of all the stakes. Right now 10KK * 3. +// this needs to be sum of all the stakes. Right now 10KK * 3. +// NOT MAX UINT for security as its not good to approve max for Multisig const T_TOTAL_TO_APPROVE = web3.utils.toWei('30000000', 'ether'); // this is how much to stake for one council . Right now 10KK const T_TO_STAKE = web3.utils.toWei('10000000', 'ether'); From bf9fd96881bc7affbc35c90164befc1c21fc6e6f Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 15 Feb 2023 14:51:43 +0545 Subject: [PATCH 75/77] making few adjustments --- scripts/migrations/prod/1_deploy_init_staking_proxy.js | 2 +- scripts/units/setup-multisig-owners.js | 2 +- scripts/units/setup_council_stakes.js | 6 ++---- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index c628ff9..e11807e 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -47,7 +47,7 @@ const weightMultiplier = 10; const maxNumberOfLocks = 10; const minimumLockingPeriod = 14 * 86400; -const lockingVoteWeight = 31556926; +const lockingVoteWeight = 365 * 24 * 60 * 60; module.exports = async function(deployer) { try{ diff --git a/scripts/units/setup-multisig-owners.js b/scripts/units/setup-multisig-owners.js index b3690e9..9171265 100644 --- a/scripts/units/setup-multisig-owners.js +++ b/scripts/units/setup-multisig-owners.js @@ -1,4 +1,4 @@ -//NOTE: Do this at the very end as other scripts wont execute after this is done +//NOTE: Do this at the very end as other scripts wont execute after this is done due to owners signatures requirement const fs = require('fs'); const eventsHelper = require("../tests/helpers/eventsHelper"); diff --git a/scripts/units/setup_council_stakes.js b/scripts/units/setup_council_stakes.js index f35fb49..d7f3854 100644 --- a/scripts/units/setup_council_stakes.js +++ b/scripts/units/setup_council_stakes.js @@ -86,11 +86,10 @@ module.exports = async function(deployer) { let txIndexApprove = eventsHelper.getIndexedEventArgs(resultApprove, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexApprove, {gas: 8000000}); await multiSigWallet.executeTransaction(txIndexApprove, {gas: 8000000}); - console.log("....Tokens Approved"); const LockParamObjectForAllCouncils = [ - _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,COUNCIL_3), _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,COUNCIL_1), - _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,COUNCIL_2) + _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,COUNCIL_2), + _createLockParamObject(T_TO_STAKE,LOCK_PERIOD,COUNCIL_3) ] let resultCreateLock = await multiSigWallet.submitTransaction( @@ -105,5 +104,4 @@ module.exports = async function(deployer) { let txIndexCreateLock = eventsHelper.getIndexedEventArgs(resultCreateLock, SUBMIT_TRANSACTION_EVENT)[0]; await multiSigWallet.confirmTransaction(txIndexCreateLock, {gas: 8000000}); await multiSigWallet.executeTransaction(txIndexCreateLock, {gas: 8000000}); - console.log("....Council Lock Positions Created"); } \ No newline at end of file From 2b410657bedba4d662e67508c8a7fb774ecb19ad Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 15 Feb 2023 18:02:47 +0545 Subject: [PATCH 76/77] correcting setup --- scripts/migrations/prod/1_deploy_init_staking_proxy.js | 2 +- scripts/units/setup_council_stakes.js | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/scripts/migrations/prod/1_deploy_init_staking_proxy.js b/scripts/migrations/prod/1_deploy_init_staking_proxy.js index e11807e..2108b61 100644 --- a/scripts/migrations/prod/1_deploy_init_staking_proxy.js +++ b/scripts/migrations/prod/1_deploy_init_staking_proxy.js @@ -45,7 +45,7 @@ const maxWeightPenalty = 3000; const minWeightPenalty = 100; const weightMultiplier = 10; const maxNumberOfLocks = 10; -const minimumLockingPeriod = 14 * 86400; +const minimumLockingPeriod = 7 * 86400; const lockingVoteWeight = 365 * 24 * 60 * 60; diff --git a/scripts/units/setup_council_stakes.js b/scripts/units/setup_council_stakes.js index d7f3854..272f564 100644 --- a/scripts/units/setup_council_stakes.js +++ b/scripts/units/setup_council_stakes.js @@ -5,8 +5,6 @@ const eventsHelper = require("../tests/helpers/eventsHelper"); const IStaking = artifacts.require('./dao/staking/interfaces/IStaking.sol'); -const MainToken = artifacts.require("./dao/tokens/MainToken.sol"); - const IMultiSigWallet = artifacts.require("./dao/treasury/interfaces/IMultiSigWallet.sol"); const EMPTY_BYTES = '0x0000000000000000000000000000000000000000000000000000000000000000'; @@ -74,9 +72,9 @@ const _encodeCreateLocksForCouncils = (_createLockParam) => { module.exports = async function(deployer) { const stakingService = await IStaking.at(addresses.staking); const multiSigWallet = await IMultiSigWallet.at(addresses.multiSigWallet); - + let resultApprove = await multiSigWallet.submitTransaction( - MainToken.address, + addresses.fthmToken, EMPTY_BYTES, _encodeApproveFunction(stakingService.address,T_TOTAL_TO_APPROVE), 0, From d49d2d07480dee8d0e94677df8f516a4330b2fcf Mon Sep 17 00:00:00 2001 From: ssubik Date: Wed, 15 Feb 2023 19:27:20 +0545 Subject: [PATCH 77/77] changed setup finalizing --- scripts/migrations/deployment/5_deploy_governor.js | 6 +++--- scripts/migrations/setup/1_init_timelock_controller.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/migrations/deployment/5_deploy_governor.js b/scripts/migrations/deployment/5_deploy_governor.js index 76c39d7..fa83d94 100644 --- a/scripts/migrations/deployment/5_deploy_governor.js +++ b/scripts/migrations/deployment/5_deploy_governor.js @@ -9,13 +9,13 @@ const MultiSigWallet_address = MultiSigWallet.address; const initialVotingDelay = 86400; //Approx. 2 days with one block every 2s const votingPeriod = 216000; // approx. 5 days with one block every 2s -- (5 * 24 * 60 * 60) / 2, const initialProposalThreshold = 1000; -// time delay is in timestamp not block. +// below are in timestamp and not blocks // Each user cannot make proposals if they have recently made a proposal, for a given time delay. // This given delay is proposalTimeDelay, the time between multiple proposals for each user -const proposalTimeDelay = 86400; +const proposalTimeDelay = 86400; // 1 day // After the proposal is created, till what time period the proposal can be executed. // After the lifetime exceeds, the proposal can’t be executed. -const proposalLifetime = 14 * 86400; +const proposalLifetime = 60 * 86400; // 2months module.exports = async function(deployer) { diff --git a/scripts/migrations/setup/1_init_timelock_controller.js b/scripts/migrations/setup/1_init_timelock_controller.js index 9d1ec5e..85b78e2 100644 --- a/scripts/migrations/setup/1_init_timelock_controller.js +++ b/scripts/migrations/setup/1_init_timelock_controller.js @@ -8,7 +8,7 @@ const ITimelockController = artifacts.require('./dao/governance/interfaces/ITime // A Scheduled operation is an operation that becomes valid after a given delay. // Once the delay time has passed, the operation can be performed. Each schedules delay must be at least minDelay. // minDelay is set in the initialize function call, and can be updated using function updateDelay. -const minDelay = 86400 +const minDelay = 7 * 86400 // 14 days, with 2s blocks const proposers = [MainTokenGovernor.address]; const executors = [MainTokenGovernor.address];

=*y?OZxYMrG^hN}Pzq<9#=p!(4419P@%e73L$Joq&J?r#@Lio!K z9xhP8?cibG{Q93&dG1j2ooPK8ntXTFOPm4t=5kSt;z9|ue=*PIFQD9?SXtTBV4pi$ z?z#9&0M=9BG8fQR?v(_2x?}-Pzk!oDAuB{!9@Cza)$QynlBz||Kz{J&vP^cKvh>_J zbq@f*9}H1Aawp0WoX=vT2YpJE|4Jl*!0~jlOrp>wg|4Bs`j?F&iYvugSNP{t=iv{- zy0nk$%F@({^#z@F!DY+-LI6I_o=*%QbfZPiR0fZxHeI*xlIr8Aevlt{dw}{+x zN$GM%U!WbSB9oHd291NX?KI|?sXaMrwpS!rxnBSgcm^Jd%UzJ$I846;h;;%5tjg>; z!0f95({7gYCrId(yRQpJ&r!zw-XBW=X^=EYBR(mMw%u{cvsQnNjt+POJCe7P} zG>PEv!$^c@{bmuH8CpMO!}UZA?CBs&rs!_hA5Jg=c(6n9?+^E3l%+_3WTBY!?DqgO9@jN2mh)zxdG(II18 zP`42NlzxmPAOPjxZ9bC~V<`(0jLoU4vM>aa)U`_tbt{S>?x4zVTepC(1kvQW=6^`p z!Y3g7+bz+r|AL5{8l(5Ko0q=VZM~&D!81v8xnq+)6#V#|z#y~yH$14cQzU9KIz_g8HCyl++!!!9&?7t@DG{PtRAroiMBMhdG zw~B{X(nn`1ad$p7OQs8)6F#hY(c$+6o9%I~T}i$I6KpdxtX!SYP}C39xo~fx+FAIr z98tcDGMfJG=b=KCH$zcJ9LItWr)x_q^x+o*Sm@am^7)^lOR<%v6-#S`xS~OR8zK2d zU&cxD8@HvVO1B zjIM@_z-{PhXhc2=mybIt7f*N*BVR~SKe{ntykhyRrS_^Q@k`-ck5{d(Hs?!`3qmGkDsz0f9H3lFW=@$XD$=ERRCNVHJ+(18WpAnuslA{KGu>)w`aO0GK(L`NM&)jtiDZq)shODo-nf&uV5ol_P3O_~}oGBkmE zTG>uW65&4KuhioLUc)A`ai+I)YJYtmJnjxoevBGo`>_nn-55yuiir4F?}0_kv~ZwN z$xheQ@*mA9pw2{YI@6gqWt2@)i%ZNb?=Aakv)ho4ENHHl)?oaXT&GwxM2v^O^$r^U zzX1_`jR`9L{{2a^05TZD(WWzR+DbaPipH1sVjHtMmcMb?AvGrtV;MZea_-x-rHI<9 z6~wRNeQvD}5dq$8aMm`1eM*h5aRbjhq^e3b#CW7$b)>g2kUAj*`IwmG?1$*Bb4Oo{ zR|@;Y9@6<5x0^h9Ld;PS^ZQQBAn|wS+`ndhKP6dn$!VZY#y;LGrXu*Yq#*U>Zma5C zaN?JyrmX9b>;9RMjJXZC<@_LAsN%#)kbj2|^L)ob8J6e~C6#aiNz||mIR`_Y{hHmg&z@nB z_ttUar`Dy#=f1gSIIto_=0~9yJm}md>lX^d^jJ1nPm&P${t&v%XM^bk;pL>^oAJ{hMzRNWKb1(I63c7a>H85(7Sow>@rt!!RB+_*VJd{Mc%$@>#SUApIhA-(fVvzx-JRdP(a(W}`NC`5EYt zojMLr5_5Jr?RU+=Js2J4voD_oE9fl>YF1f1xhj@y6ah3RVA)+wot^PGsRT2)0xIA# zWE+fk4@K5}smbi4u!y;_GbX02a4Ds)S7`9v`uZe#yn;YSHSlMffxs$!APYhX29!@a z?Ju31j!@}i6sns>8BabaK$whEXbNHT{us2>n+$r-a2rhU^l8G`hA+=db?y=~(WhMMeP} zkphNb&Qe5t-hGOYUEHC{)3bYl%3pZndrpE_EuG*t3YaqS%d1Jy$)Pz11GLdHqrC%H z+2fdm*%t-I`#xUVJ-ED<%LrSgJq{AY%4hss6&O!tVk>uw4tras1bAx$8JqjwgBAPr z72>e-9jzYw56_=UM8@0DUD}(^EGZfWgDTFm!*utn8V?JuI>G#XI$AS_>=eJ(tf} z&w*^BIc911QCcuWBkhQ2KUre6Gv<*Z1{wd`qYQ8P!qN}uWuNC2yz)yG7Hp_BTXeB8 zBO1&fskF?)T6O0*W(hR21njvDt3NCiG0-t1G$hl@#A%>R#C{O2w?=ER)n--FmM6U0 z=BzqgV=;Sd%i}ayreO&umeAy^MBv5pMw@S{8lGAZIZTYT;OLy38`pJ{5@V_+yDibNt325cl=P)g9H$+;f{6V+(y@XK9*0c>em%aA9b{~s; z`C;7<2^vdtEX1qz#A$Z;C_H}QxTA+a!bBXWtsxbydL%2rBaNW6T(SE2x}<=E7!4Bx z9-$D5d>?FG&Rf=`wlJYdyB!(ega7=ZS*11}6C)e&O8Y7I&6+QXQPw#By+IQ$WkzQc zDPi--UDdEOXJR)p!o_R4BmfQPn~Atw6#5q@|5ja!BRC_pW^u~IGflL8B7+(Mjnx_zahs49<6ne z0*#}dN`Uxco0-oqYPLM@{$qAxn+{XT+;k(9=Zdrxz^cQVei4z<$Wp~qVJt3#G1=`& z#1PBZD{F1wrES;Bl+h>GYb-jprn!`g_^=gK2TNIH|FgWjBT%p;&(}mWgpfsBI84*8j)SvhrXn~i^qDoB?9_tEih?4K!<(@a&Gl5# zm~i=!fL`PK9Ju!Anpr=MK{k!(FC?*-3V^h;-XMpeN0a0zv#Kd&Y)rMk+%NtEc-iz? z@>zloI=Y6{q}G2uQ{LN=?H|naQ5$Z4=;Lp=1xw)si~I8o*Q-KO+N}2Q5qbU{rzQLp z_m4-*O2va9@=;>2-oeRFk{eA-{8~^+fe4gaNtwKHemdHK!UnKIHEWN_q;+70^TJrW9GQ%A?Z?4hZzsjBAgXR7HeC2kw9^JzE2~X#rch z8PxnhXALWPlGR>@7<)`o)%dX6-^1vDauiS5!cx1|FAKvYFossY`){Jc&ZH}Y>7~)) z3yz9jjr34_qFYXBMWPd*D7^#^9g{hyG>Tu)EY8?_9*PfAxzy=p-gJLR&LeJO$|bma zcN-6+e`zpTRb9I?F}$qgkU02yY86~Ft2KEt?=|JS#ypdZstdpKP?Zo4qr_2bA+=~W6I`q#GX<}!?7>mKHXmOQ zyy9K6(m#zrPb}=r4obi6NjYPHvqKvN&TJe(6h~W2r(+o@kxHy3P$eUgR27alUeF^s zg^8m$LkyKwpwhA>^RG=+(a*K3tm`=ns9V&}uLmz1Gtg8r&UXK=7j)FOXssF0YO)$Q zvS}of^x+d1$jX4cSZFQQapq3bhwf zEk#Q_z9~~n$Z?jfd*g7CwNPSI5(0vha6JI&?HI6!B0PW3fjWX#d*-ndh$gQ)b!2&y z*d1?GPk$pm2Mtz65&T}#{p+9+Q_`CCJ)>ABUet<+PH4Uj-&ev2joH&-qtNe_Qz!n` zU;Vor4gRAvHdL+ZEY9A~>IS?gBimh-WN*bZZ&5;wgp>c$fbB}&?JL(814N~h`4O6! z9uA{z*{u=ZiU6;3HvXfDuPo^Pq=dN@r?fB zmmx!_{bLMZTID%c*#BWFfnn}H_J4-CNQ!851pRLrD&XnEWwLB)5czd4G%?Qd(7WwU z!^>0b(Iv_>LLDa&Jvh243Zq3H;#i;hWbHkT#CNYFYtyVJ6~gpxYnT|`y`d`TI)_(Po zxD%&ncbu?Kf)N+q(Qk{8KT8%3RSylV0bQ*R zeWo2KOeM&7|C3p%w?)zk9u1THVV7mooTo&kuTP`mH)q+fFTT*N?2BLdRvNT?sLg*v znulZjnBN1g4$R5LSosTlUXta#agg_|PzO~L`7HjJ6FGx1H$)LN%wZ<00@D)iEvjgW z|B?`|OoWDU@@V@L+lV&U+t_c<6^$$045!;Qb#d}D5ifD}p^|gTZi-xKZ;A&U{l4oM zOa|6>R$J76vljT-=g^(d(*8v2b--gpVB)3Cv~@PTJALKzSAJQsCsymTdgM`o2*k7; zsD|-jG)aE7de<%2q`jj5vx{Bx<%i+sdVG9N2F2LV(LcQ4>=++u3>o+6-;O36eov=t z*5y7o)`yGdiwt)#ze0(m9%>Bfa=IyhTs5-{AaY3A0!V;ezE^!~ci?^DH|)`@#HiSg z?|iTe$Y!yXgH#j#;T7j4^fDqqe4N%?&D7H_@AE- z2j}+%AObrAg^BfUj9eK3zQ=K2G6LVK*J(g@`FG47$OzU`F^tQ<^!>5Hj82{@6!H-7QL~6hp_EQ*B0`1$EIL^T$6m*^l+XkkH210>T zc9Y~J`r6=}>ZAlI<#YaEmZVm=b||%7CoL@4VK~up#P8({BFxU?BEHGM8yjUZq>br}z1A^Yx9Y zFuaohT2jrFIqo3*Zpv*y3euHkmm-@J({R#7W?Gz#`k|09=^3F-IP=bFOe9!D^H50G zR<#N@qjB$NO^X*vx>p8EdW0TGY6JfTXM69*ID0?T@4M7C_J_y?y~vZojGoGb8Rk-X zBg>`82-nk`;?!rIwk1}qXUhS!I$k&N_JP!q2zey5IB3F|*bPzVr^Gh_2tSmUpE?ha z_|`x2f6Vq`CpA5=&=mYK{J0=uyPoLt60+f1;oIcy4z$aXosZaHt` z6q+_?+9t&o$ty!eX1K@2P|5ZW$PaM%4|W0>e|}h0G|94~MlH4q^nphCQ8r{ba)BLNou+L|I>- zF1AGCiFA~=TIVj7|K6tBdR6UJcn(Z@F){&VK{--t2J!?>zyo(ICRtKHR*oL!FCKY+ z2ohlF4S{47z$>Ux!LRgzhw!9$B$dw9+&zne<}9G2*zVm)*je;`7OT|!1aUmWyK$XC5e_JWjjt?1`Dh^y=s3e*u6 zjA?VKJpY{3#ADJbhDxdsHv4-_DH9hb&*+U-JleYiFCqBVJk+_#STFnl~-; z&5r*BYBO>*@_9~vtzw4*Dpg+qx4zZhdMl??L|WhM6MzHC5$Nj7VHg+35n?T>937{Y4o&Pq)Y_gdd6Rqm! zF$Jrc>KaW(NTJoax*n?@Hy@qi|+pYc#%rS1@-~i;rA@?6#sh1Z`4VCj&zy zx$|qw)PBsn=(SW*y2vEt^nNBQmo*o36<>S^mqxWt_~?iRMpd)_9xTLZF7{P6k7WmHc~zG;+UQpn;k%vQBc^?E|3iJ& zk&GJ+$r#Wn*PR%4$cmIg9SiqU__oke<@5;5#%oDtQtH-d-h%SI>85qIqDfl}b;V-F z>GkNBC-+(~WB94AYK*)Kf`I%q370!4m-d7YtvJ)&k2l{#_bnyjj}r9J-t`L0$I)hG zhfLw;DB*v%4S`I~Kl{bF=RX&URnp~C^T{glmb8c3K>Et3#yxOg6Z7slmSmBvVw4}% z_Laor4$6KL*CtQD+`U}668(t4D+aU(64Xh_!|#sgjr$Yfi?tR-4Fz$A929zIm5Bve z?7BWa9K?Z8=t_a{2?7`=rT#1mse)>SiZwc~#SRcVAO zs4+LmoIL5pDNEh{OJfE@vD<{wGp(e^n1v-h;lX$Mg2q>No($w$S`)GJxOg55S3mtbxmj)xLZYaBS z$&>pM65%!7KBZaUjB&g~S}Ap!nAn$hpL56MCFnB)?TFxGPk=f%eo82?yJk+IkoWm# z27zmHIRyr)aUic+x(RR%<=~9x8am8Vde6^;cRzrNl;q>{9Q=H6(c5b>Z9JbsSe#Rp zZI|T!^*z0%z~uhrO?DtGf&qD=QV9cf;JmlD(8TD@M^J5nsG5#QaHizgq_+qA-`2G0 zY}9?)ZjS%E&+f9`>2^yi+b1;;PEv-agH&8z9t}0X5Io7+gQT3w&d_T1&kUI4v#(*? z<64GKH#BO${S-U(rjF`npkJyTO>+D>kFP7)28SS{3HPF187s?>H{*H+lU_t0oMkuB zwieAxyDZ+uQ(V6S3PL{tN#Ia9`?n-MYOY)VYlE)=B8JthmniO9;Y1|KR~-mTAFcIe zKsVd>PR4A80!?ljaV;OYg7Bkjgr?7hpqJTSFJ?deS0xTyM5}c*)CQ!?l_W@1S9}#e zT@k&9&ULgVEG<9D=5oh#@^}1m=6w74d{ZNW-~v;U?PsJw6~!waCHBv`IB#>l#s^h` zZGiEkf16{?A&)glR*k@$t<+0Xu^1YNgA+!o?uu{L zNZwdUULiZ^aqzCb_cZni%2;aLjE2nNw(E>*DspJ|9k3u2k&192KotD4J@W5*dy1@m zB1xmikM&BU_Y+hFti&(L9*4^IEA?YS>sMx_FUwxhYcMlV6Cgi@I&$gFb3PpY^^t$K;p_8v=@(nm!XFtK| zw|ohas`{AqS8s)AcpArtmx_pT_?+GZAe}Qp?FB;-UFnPtgyBZqPu1kgXw*NtxIWQaGoZprO+MKwrQ2PhNznez z+eKU(F47lWZc4Yds<0ib$8z`mcI$fJB0mo7=s+1y1z54Zmu9)~!59a`qsqzlv1!0A z3UDpFq7{L^rQIfqy501fnPAc`hL>KUjno9+a4~1GW6{pF>!y1?RxcZPn6U>V!D=&Y zVDllg-+wGTh^3&dWZrELm|A0wH~kQ~15|OB_ovb*Yw=ncOV{nOr(WbL4;}BnYqF6B z8@S|u5N1?O6R0G-JDlStDtX-wabi)U)Vcwpy8rJi*W2f|Xkg^slQ9H8&KD=#tw1)3 zJPBY6b!|Yrog$w+sL-`s7(WN{)5B-)&%KqgI2ug(GH2@lqw1~uqF%$UZ&K;*2C1Q> zk&w=z2aqo5mX_`Ysi8ZDZV&`1>FyRmKpF%YLi+jby|4SapZg8WAM=?x&+}NvTHj@U z^v*9x@ZYs2`l^9MD?P?oW<6KL)y)eS7PW+_$ZshSEpNI13mAvQEu3}tSIXzf#x4>Y zDMq<>ZW6p;bLlp+Q3jpNTGnvOoqJ8pbcX(7Tk+J_enWC#3`rK*W%A%)JRQOf5ZKZ% zt4{YiYQpq=zN5fwO z{gzZ9<>LGk0>?Ite#!e!H{whAd3uE=UlY&UbcVQzLThz_KG~I+X8!}mJa=5=h5Uet zHluekv7h_vD!6c3_hfk30FQ1AM9|@a#P|eDRX716=*DR;y0N!rikMOsNAN4FE>GwP zr?;Vv*=gG79gX^-tSv@!f4{T_qBt_FJ1e%a!l`hPxD_Y(UcL_~p~3$oL^v;%ZnaVx zx8G>_sb6KDrxC{AHYLRU#OUO;9R+Y>TH>po&M;J!Dv$OAI+*gqZ+_1*B_UP7N~$BE z9JX_M3{~YYYdv1Hl2?(~q}6rQqxJbyqsZb+Cl=}UaKllX<*_dzFB%p<)1HJx#K&F! za~g|NWjCd-nxX1L=OT55{a-PC^~Sf3ei1O(>7}$UTgb{nNf|-DL^oKB@~4|{I7&#% z_Mk*w)rRj^vf#T~J*^xc_p_xpMj-Pjt~vu;$l|;Sd2tB-H0g{F3q#5$B5tidMPQ>O z7Mx#CwymAtwi;zoEBr;E)XF?_8P&RUasw-X|L_&-RQn0BnLNwIVwOG{#XNmTx^7XY zS*{#t1ylP=N$C#`cBg7H@AM{W!wYNp26eWZ0h;aSJifhZqq<_~_T?20EO(2y31)Wu z_Vl3XM#&)Y!O4A00NSLvE;8l#_C-#J$6sh`fPI@`c>QC&KPSIcC|TRkk#}s|zqXQZ zx$VPXMy2E5S6*cqsXi~D5PERh2&oazw6;5_e_vzFW@w1hx=TPr2dho=4*}SGSHoB> zax?sLBj9aHKaR@c0#yVrlKWM-!<4R=+l*KJ*xwrG!~VX)z1;g^4PUG)Q0$;KVDX2J zEa$~lmG#f}bg0n_Z53-lT~CAOkR9=hR|%< zLzDM0rEFG|)FNIJ1Pt~J(tg>48qT^|tKAgI7Bb6>K%}FJF~ZRgJnCZ!CZKSB0&cbrsAJeau0)YYlJ9RnOFV;sAfE zMZ8Qs`Vj)T=B;JjO>#P7txj_pZzV$D{f+m@VocrrX@?bd2)D{7G#vAl8a}$_y6uAp zfo;KG`?O`iM>dmzZ2?5f!0&m^sI!!;mbxH4Y14*6dn}{;#^g9bZ zt@Y06k1XOZVR{`_3W~0bNyPbARe$VY);*KH{GwX~WMcS^Z<^5LOVDUH2#K!gt-rzO zN|%D@>CdmfQ+fzhpK}>R7?A#VP`kBM#znMJE|vZa*O@3RdsiIGTTHhw^Aa%2*GG9z zp@Z-;?T_)eRP+|nL`1wc%p@DcBe#hb-c4Xc$_clBshq29e*m0KnkEj6V6?#tT$Ba6 zaC8LOem>dG(BuuJt0)Ez>c7Wb{%^(1rZdXA4bG7%8y<@6+=Asrzb5?6M3fGbLk;V? zL+EX+LtpZ-v0la3&E}P>+F6CjaXRPx)D@5eMO>IeKTI zITYp3p8?~@Y@K@NP6+cK$-P(|e0&8g=9o5EmaBo1ajx&dzCWbzRKquf&+^=-lI_aU z%Y`LTJx3-nT0MTAaGwti`+qLhM0W@2mS7dVP=YWG#3(AT_;;HG%v2y`mTo1VYnfw` z3jdG7)RzrIeY`*02;3qa^a)9? z*1Mq8QZAoJF5}iJ^7quAYSHBnOYd)pqx)vv^uZ`^ki_JmY`&#^S)fAdLS0g7mw)e% zDg#@}2baX(vp$Omy}~cUhCFt@A|o81!m^qFVpUJnS{S>-ZpF}XfmJ(Y;a*SLjm!_7LR?Iw zusFFqJBMnHZ%!Ip2;fR8iJi;O$$rew2~MCdJ%&$=lbYZn&3R{+Gp2tJaVi&A4AHude_x?cfbNc4oN7Fa{FbnxR5%8Fhzj}a<$!=f8XUdE%8hY(b1)7vTXC&YQ*1cEtC3R2wZejz7jS{6cr@?k@Wri2V7*?iCRuaD5eu zW-j7TST$<<-WMe(^UK2wDS6Po<{M2|T@}n6GvI$NZ#KXwJ6w=%> z2=w7$!XR4>;zErS%{~tC`wAHZvI~x>*Om$y&;@woA7;SwX!#0^DH*?((?^8}JeyMp z55*+6iA`^xbi*X|usjTF((l$B2`d_&nxpD~-XriXM>2c$xAuxEKf@RWD4G%A2t<9?D5q;U;`1$488K_;Yyc~5K%*^C!@$^oltJa9vq}2)Z6-!|g z^o3^Mv)ilOt<1O@J5Pbnj5*-@r`tRJBB+NcIPgmh1V`6>)4EX2V7(5*-z;fYfc9cr??Y9krb@33851-ITal_T?F^CzIHD~b%+ z6$>`CJ4Nc_JC@B#?yr{|D0~=^P`$SXy21DXaU`C3df)Spl2rb>PH&a{fldVW#;XLMdVT)LKVN3^ zJ^zzj3|Fb7L2W|kc!1UnD$fc;gK1|kodPgR87++#{cS5RhZ1u+lw3}1mbcy3|9A`S z#9LUcjHdF_H#oj<_4TE8s_lNscR&9NHYNSq_@02TWF|%?gteA_*Gb1q7v43r71$BB zj8t`3kE06u{_&QhW*uzO)|3fEpu^qB_X8)65<9 z$yxr@xCARxwg8SDiW!ox>rzOIxGn9=kOlM|TmQ3@iys&Rc|Fvez>YJ3)hefs|4R1T z?q^)vIgAQb2`#{^N<5uW`E+-80n~-7l*l9D$ckWabnS;KQ2{LS>17~j(PP?}7#xzK zjvV&Qb|B*4v%N&j;JdL51AEudYG73)-XzD<q-M4|4Y-{Mn^JTR$F z(LA5aE@O{!djh=kPu=4@AZaj3Tx=AvLQMJYRC~rwj-K>s)M6qw(P#`jWh9v@-)eH( z`9+0vE*j7*%UXPRbmu`#XX`Y2Gp8;EB0Z?x5OA?l*t;O17|CpwoIU=Ma0o${YR}LgE`2d_lEe=i z#a2N0a-#&=x-Y?R_9?Q=EFLnWm`mHIxhbDO1SyRzy48XLJrO(8&-z6mLTKpfM>Uy% zP(AzHM-Eo2mHfJ{xXI3c7nn_q*MDZ9g#Ruu-+fMSglOYOgPgl_fA5CtH>U3Pap=9X z`Wt<9p1gaEwixe_CaLac0gm&*h;F)67kLv~;XfI#l1`h#aL#ys@~TMFoQcdZ^2&xa zaQ8HS=#*9#WO&&)L*zK(?E+1&)pV>-dWDkMP_Cny!xSh^y+?d{i-AB(-ARa#i=Dca zKCZGyFt4!R`*QX95$kX&i2&Dv5OagN>KM}}L*xUj^BZodKW*#WW#v?Tv0ho0TtA#x zs;bESQ_80a2*NgsNfo+xR0$${!kQH3<5zz4AC<* zyg%e?LPl1d#yTcQY?u{Z%}e)yQ2w{B?uUz-u<2CiPvNT7(@W3A^w2*^`ryxxAFF?5 z!{J3B_n>hn;_v@H#4rEYuN)qdwyB?bjmLj%o(7UXcW64ybxjvtdr)PM|2!$e3ZQW- zp<{%3;TM*%ib^)2lbT~r|F5^Z@_j2b^i3=TOd<%1{Txd4F}V(IGN7axmSa^bgu05z z@zsBlT_5X@dvZAyBFzTj{w$}JuUq77TZFMrMu|5+e z>ZSc^pqhk&?~j^X$oj~$bImgrp#FAFljeBtVQmu0hVjyK?oLB%n^P1_jo3U)kKsT?LWNK1Y7ejqHv}) zmpA@rHvtuaZdH(yQMBh0;W&=?iojqc68X_#cExz|#{Kr6gE^G(+LSt*cM>Fn&&Ws) z$@RDuiL?YO?V%@yAL^Y6R~2DPu`27%m(ip13J*9eCALwUoUrdyQ#PN^a9hP}s>@Lz zqt!0b&nfM z>s3If3KJ77meq)RMETPa*%kyUS&?oTWff`dnV;&a!^^ zu!R{Y^)8h~OMD41Xx3`af5vw_v>hw%XryDnXXh%w4_6?vnb$M?ni5Q|2t8j06 zCojx1==`o0Io*=)X!`zoR8PN^KeLkD>`D@o=Ad)U5AFy6uf7pX2Du3OAG#TXYaxaxH8To}8gp~CU&qIYkv%~#vF-J;Km|hOW=LI5mb~v<@j)im zGYZRA7WG+#Pglo9B>cYwm=?dpV<#Er1v1I+(!@OMu)GBc|mBJuM%wo;M~Q|Nc8X9<77}^UMmN)~Nww05&)) z;p=h2%E`dLaT|St`!italdqEu4Uc}~%Jp)poG%(%&Rm&DMu~tjx^eh97#Y0DnZ0LE zqBT!ufrf!RW1}3MR9MxtM<&$d%5P!#z64c=57nq6=i=BL}`-2_B?Rm8eWdh zKrO^F#!S|aomy4*@K+c}7|&G%6z|fvbwZzpFw1~GwvLYOb4N#O`N9qQRiEeMaY-># zo`GVA9`WXSXv0DX>78y5<1 zjV65}r;DJ|@d?k@Gene6ZXf#a%h>n3;9Ruj(3#L=4o#;1sq9zMFXU`64X}c_*4ugB zkQ->nY2FvoGwP#TUebiRN&WcHKlii2LXlLS4it}AYS`W^dx`Qr_ z*F7{~h^%CpSsF?z`Vbjv=^Ir<_FpA%#u(tKx05d0{3BawQGGrHwo6S(8P1PW?aM<4 zeWJpPD#DdVA?v0&=u|%nF6Px{@fQ0*$=0iEX0U)FZFK08QQETgJ^5F zM|2GwEq=?I6lNvWXr1J=aobdKffaidPJUgfs z&${1jDSo{!dwh)pEHNc}*q1>|R<}Wh3nnJ>c*(QPS4Q_^8~sG0jv!rI8{4soqPko^ z_gUN{g<>d!Kuf*Jamh0h)GgoZ(}}gCq6obE1h>{u*K^kZ-A+bi2Xkku&HlTXk!t6E z+P9bM^T=4By)S9eNBwrh7Pq^2P4*?e!MY6E>JKtAfWz%9PrZC!vZM$lh-e4ZVS=IR z%}Zq#B%$sIOA4sY6NiqH(D&4AEKq>IxZfh9VQ4tgv`GmfQ7k;Al%wt^e(B0Pjch&# z)&Ie6F9YZrWl21#K|g+u-DRxoJ*N3)PGxnN(|~t+W>aqsfFus6!WCcoBW{ZbL}Y!V zLYx6ubLUf{xVMk@fLk0HMTNB4Qk?vJVGKLR*XaUA>TA!`a*FdBv!9zK#|A~-IR%Ad z{Dwi3ETtBGx2B#bY0tJtEP^1Y+OFe9JdZ3dfB_?$O2=;Fi?Kx$hYQ(I|ATPUjV4Jt zltZ=`ia?W6U$wlFTt}#W(`H}qGtG#fBUedcC0Fjs@IQ_hYJv6`qe)EKIjj233MrsUZWIYuJr1psf#;iY`w9{3g)&G^kJWS^=)`$S30&Z^f+;}3UOh)e4Z&rZ9vH+X-<5KHz;R(vuc9xfHvi) zv!HAbrOMbF&QRvjaER=r^o;KF(LEXEgryn9Z~A{i;!j8Z`*PuSWc}JNYzkX{z_biW z=P#o5WqI&0Qkd~>cb@`>OgJgb@QU7TCJ`Hx3_sVgDwInEeUN%4ECQXa&5Mh3&+Ypm zY9jy1@Ou|tMgo6iL+Ga2h=G^clb{p4*FZ$j9amw!lQ1>41n&AflM-_B)Jg+v9_BFk zLJGhA#1Du5{ELkd((k)MZa$o=H+6SEAn%j^7Z-YJECTUW1~jSUFr1#CXb_Dc zz25G+$x|Ng#o@7%`-T8zZ%oE6Rb`K6AEVgyXAopl2CXVRsJ}O=9rjInq_uyTwlo>I@=9Zv)S|bfw-QIDL;Bmm#Ycn z!ALp|WOL(XrfS-gD-7!w%sEoyHN4d0Qih*$%57nteo^?<9$ZRJ$qnF^47tq88{_=} zbo#~Pv~c$eWt8}XV^`9C?x1Gw)AAO#n!=zQW|Uq_M4jXcw-9C5+Eo$s=ra#pGE9M85NHlrY|Vk%rk&>Jdtz%;}`$}IzOAa~||{U8Pn z%`y-X&Ilrcoh%OXU-AKHxq`a%>t9tMEnS6#&(j&cfe!VnKYEi>9&`R#g{EY#_Wes) zu{|>aUr;w&Xr)vR!r1ro;D;WsTYQ%RQVWH^$bmD7bC9RJiYt92nZN+q zdn~CEgHe+x_DIu-Vtd-An?!Fl*@0bA-N?esR?NtDM>+LSf*)ozbc`~rfH#Hi{x1eS z1;Xx!#EHA9HkZb{g#)SpB-qJDvv--O(Yf2y)}oM(BE@(8Z+3;YUT7%66?guqy_ZF} zXM}E3HsLy&(8;XThN&1pQijv#HErvSOC}1Dd7 z*r?4f%yufQ56Nm9IbMcGj}!8(cjwK1mu2xy!?XUhsetugMgkF5qxfrBbBtI7;Iw3p zXaD|NUIJa?=f}=<6+_ZYzc5t}5uRc7Yr`|i0WQDjd5?8apjC^qZ3%B8n8|I{Mmr9{`yup`-Nif!A`xQDEA>v^|7hTdGr~t z5Y4QLq&O1q4$oqOv}u9(RY+nfyG>OhQUlo}e^u7ob48XPRtX(x21L5Ie~g@uHIMRj zTt;nVON4=-!%Or7_NsS2?dif?`xWPZK~T4l*6M)>^{;&O(93lBy9+UdG4>V|u5|L{ ziZE?3+Nv{FbG^dL>g#Wg%5-l=_IMzraA_~PbJ0u9&+!jZ>d-N38Voz#`v>0-d|)3; zdkcQa2*d`DHTMoFo@s{=Z^m$DYfWO$7p+wzek$xvlQqU6)@lY5BB?|IuTbB}4Z?{d zJQO2|Q!b}qLN+7|2Siq91s8Uip~b!1>xn`R}@HQ5m`p3KMegl;~XYJLgf`bwBGa!52QrxoVs| zT6`j|rg^Vu{jcirnv-9mPdC_ZD(iA|_odz3eG_=>VdJ;bFB;@PL$>%eb5V^*Af2M| zSv>nKvWk>grv<(#cI@62K6e~9p)2lL(;=q?F~ZeRKJPVRQ(z~2^7m;a<{7~oB>jS%ZB(5&LLnxU!jwg4MV(>X6+5SQ1-Ev`@eXKZQgDmNUU-C z<@$rC|A%B?rg*NF(TXI{MLv2#;5up_UvnWeU#g+|6BP7##F~P`N>d+Eh(0(`n2cWi z6ESHT;IU|bcyX!F(UxNit59bHV>rv?jfZ+1M3BGlfDXhH#l9)}79!6;jsH6$=&gwP z^Vc>!^I$aX#F|Ux7Ei9H=rtexPOx0c6uqh;h@@4Qn-3KPQM(#jBUji4KAN4BM`u7z zqi$WLC(${u=OxPb=`n4fsLm<&$WTU0JO;AiPW9&z3#`v&h6+68!M))UfBlW+=}`>lE)WFbq7KXl#)$6lKuasY1JpWVy}4wj zYM6x9c>{EIVb05a3?AXGdvoDf8IU3yUNz$=6j~FiWXptFR{F;wSRR|iB04~kG=VuQ z__MZyFtM;~v+q2w37DZmDl9ws1o3R1ItUO4lu!xCxN2;)dIlDP9o3ZdnUosJq&+^} z9gN@=14N}Yb@<}riM7UaDfG1=0)1r-yz5}~n-}Gs|kUt7+y%A%#J>d|K zSEj{MH-sF|ybOv)Fr`UAG*hZfr^NE2o&+($_cP@ig^~M~*E`yyNpX(4QbRgY2~yvF z=A{y_?q6JK1kiHWPeJ&ZQM}s&PXp)yVh}WHfEpkc6@dWo0cPc%G`xsFeI|bf>LW4o zN%_ueb{YUFBz{95CVKD6YHS;iYMU8=qf#ase7Tg%0?&nxBZ>M$=72xYyA=QXwBhfbLY@#UGZL z6k2ClnZJilEJR34EIQ=*Fy>qb5hl=S^N{}>eNJpo`Hr{qHi1;Ex;bkHWryS4hCGQJ zffr|6mppQ4mYi5p&G4Z&%cb}xwmr`kSaV>-ukb&6xFNv=aW?x7djun&*;_Mf4pt?~?kY$A4)Vly{?eLxC;-RF^NIg_g$cn1Q zSktfO#MNH$#ahW;T8Ox;Z5*i`IC`Cng!ep8gnzu=nopOK;UM+|I_;hCKGW6+1w*u%@Sq>9`j-VXmT&ZzrKm;_@ z|1JfS`mTzi0z#v7yVU&D=mC1=1Jz2Y%M)0*Xpk`w&qPR{F*Zj-?t=N34T zy~)74S2#i+^0(Ysclj)K3dpi~HFb3YwhMzMq(u?X4m*!K-KU7RN*9|NR)j}7_PL+) z2mGv|5O!{D`f2adpM(S&dhtBrD^cQulS1SUy9hG~^F;9}9|@c&vwbuRSQ-elci_Y& z_s8|7+{D4Wl5Bhq(vGo2qFmgc+p@o8Q7!VP_q6q!~GoZP#?9eL|Eht10ZQp3W%NXmY zKLm88PX|}S%2^oWKX$*54|={j{&T#XaYj?c6Rx}egIklg0pxvJI-h_j(@+R9s8l@H z&}nZFA8C4PjSgGy=y22C2u_2P3SX=S*}kPIIjR=w>lPDLC<>0Or~-$Sh>56U+#ZG5 z#oo;La}0m?{?g;h*Le6=tp%xLj+F26aHZEDCzDSnY2#~;qL^twFuCmC-NzRitA_hP zm=}1~aeZLr-TnPrLi@=^V@$e=7WjpeZnJ}LUpK%U-vne~OMB@+f5QqA0M`2V*c5j| z@R;tRv_n7hR;s1iYX7mcz{`9?@_*RsC)-bX?Dv9cwVr%(>_X}^jqP-a(yzC3-PLl@ zV87Vb=2hSUn-sU*f6a)CxL@VSkBv60ngKD@q3+i>^q(J!V(sRYRA)vNDF#%+8oz|X ztg#bpyhyb0K2}Pbyg2UkX7Fg?C!HI_NHwVvJmtvz)WOrpU}i0S+!-dEnN0Hj695fj zIr@vLEpSG>)>cPb0{DHl=6_GHGa0LX9q`z07YToZ_|CK`OW+fhe$i{7S4);p%y0kg zV6rrTf&WleleZd@yyk-_5^VW=(ma(HPUCzEdCAdrm{<%oFxlqMPTqYQs;c82HT2=v zn@1Zo>yi$OvT-s*I0CIPMZO5Gyp zj9oXT_B@e{MWeplkN`SolqwXX(tW-k+T=xX*YPeoOFY@bz-lxt+G3JQc0y~HO z@Ur-PY`3+a^z$Yow!ujoO8cVwj4{8;zM3RryOU!pHq^{jStnZlEYxt@CflyYr5~t> z_3shD3hQ79n&u7H`68ghPaK`^&SU7WXAp0Fhj-uy@OeLaY`~grCz)?Fiw~EU+G_EA z3BjPAY|RoNt+0<05M5vBs?mwH)+G{r>Hg{vxJ&l=OkM9prakDbsM(f2t@COd>gc20 z-N3D^jhBVbk~x@^`2KLP1GCB8zU+)L4rHM^DFr{Re3>n9Y z+XCJ*Z`PZNk7pffvkq$-r2l($y!`m!T3(+lybIhMU&9?oRgNcDW_u$TpQC4>@IZ~Y z78l!fUNh^X5mcYGNKx|-=rI5PAr&|!_VW~BrG!J+bRym#BM8PQBVPRIJnna_W{aYH z^M5?@>R75$e_Th&twqh;4!jwrV!Ro+Hv8w_48_mcn7_v$%T`aPC4#?j=Y;t1OHOcv z<4K>~Q_X*KoMHXEtMU9^trE{%sa)f}_(7pp?2tbv|jXGQEyeezq@p|3g z^b1Vk5fY5yC+??nkNR-ui(q-DuQkR|z0a`7y4?jW`hJ6232DH+PzT_>n~iYQ*KCdU z;)r8nYCu+q5A9VbQb0GT6>h>fi5td-pdclVXuy|0t+yYzRa$9UQfp_ZGslV$h6Kq@ zbCeCxpj$wen_vZ;L?}x)B-^JvY(hPo$f2iiAwONAZgGw8wMPJ>rs~x{`q3pet5tij zDio6Xpj%87fBBkp?IYZ}jqz?}s6XyRZO`#X*9K8DU<E+bu-k3}yP93q_FudhrK2&Ia5w65YA`0L+2XU3uS#LbDM z{7PWy&l;Fq74Kwbtcpg+%wt_Pdz=xAdF1cl%uAiq$>N7Qw{6MnA$qfq<2WXaO=ZRW zGf?5$bkxv}X1cA-p*?9ILf< z$~#?;78atJd&5A)J>(d}dnH|jTv28}!|TVn8QxOJu&Q(B%Czqrl}7cBkgRYwQXix@ z7z(BpIXgxCIYR{C?1q?rt9S?R3~P)zGD$cnw@ZI70zCsc)tG+B zu40p`q{zz3zh^rR6!JQs*7HO~oV+8urrX3F>gJsJBMkEYJK3%N{IvbVsJ(mv*Q zW=v3zoj!H`i*DNj6ULvGC1#^3NdZ57RUA!kyLm%DK$bAEZ&QTG$iWtGDb+Z-5~vk} zh`kUrrgIgn4Naw$|Jv-1lFq$vU+~`+D6lH^UpL4Yf?$*}C1pkjg`aIGm8Cq-} zQS7vJ(!B2L+T&qcKgRz((ftgD1%lIDeFhs}250a3jiUn|*224<=V^e_n9GPO7gmOe zTpfQLKD)pm^%39yZE!x;;l^FgQY-+)cx5m*{R>)BV&qokI7n1coET{$hqM)On65{U zFU>d@<6#ooQ87z|QL!s7F<*u`r%Hj(u+W58`7NzHeYzG0fhJE~Qdzc>(4$V~%m#K^ z{M)SNprw4_IGVSk*4vJYN(05^CLZzh}QwFluG0yIp#x4WaEP?-YX8_3FAY0q9UW;gC zn_H>yDdDrOq!;7AL8ZTDR-}%_3O5Fi_8FHVONfNI6_#?c3>01AexA(uN9NrVVkoJQ9hF_ET$rJ#e%%*5JHMt5^a-c2+q0=|^w4jS>+*7R%e#s15! zLFEepH9qb6&L9sO4>VW*{2_?IwN4w4sp=n3VZ;XGg&}l%_bN<#B@*I*=u#h7=}b1n zvz5_^oP=+8!X|O-a#)l{ss| z?Rm<}+4mV)VK^yDwqViPDs(FXkph25_5WuTkW~aq#d?(- zAO7Y~irNj^h+qQyd$-KrAEjUG7F2j;b5z>QW2agOXE%0B76ac>IWWKfqTU3uIf$L@9f=CSG$TTeKa{1*u&y7< zAcjI7?#oYCWB~oYrwHW7ns6?7UO`i2jGF(V)iRaJtoLklmgYqYwXsM$N`GBhnO)us zz%|iDIEQSFHeG)7JIw`lm;aK`nec{2ne&*Vbn^>frWz45@SVqm=9#fiVh!RFaeV+<`f{)K%U z5n@hbuI&=?DBfGZu5h#3|&W zoOUvQtnDH3fJb-AuUwjP7G`U8+C}J)k-0PD5y(m_CQ4r5`(`+TYw-DBiA5ge@pibb zzaV?%Nr1G6CPI&J6|i7JyoOM2MP()^-c%!)zvF?7&=m~1KDt}BT+-=i$Z*nq@c3qD zOHppa98dNM+3-TN7=fO`G?^~mc%Ldy3Y&ScKS_p;q>wT9XEhu_^$aK;SqzH4)#g2Ar~zb9%#~XbozoidEuURg@^t7CogI&cJWmajA*++W$@VD{PR7 zl^(g<#Mp zEO+wq1#F=ZI_RHHs!@Fin3`+h!+niQn>*iYvII59Lc9Y@MI~ClynYk#gN2sLWosL3 zNYu-iQsAv>koc7snNGz9PjtVly4;VLMFnidjrOdgn0d}d#X&6?&oR&9#Mlgvg42gD zSK}5XR=orMLDd#=()us#N-EagJou9;&bp z@E^8x+q0gK!20#yKq41x8G#SBCsMl~`M`FE{P~Z}2DPIx;_X0n?qDDV>;XNS48q)F z10b?Ly*vC1FCfY06)J6c94+f}H;nx(y@}tN!QMUkM}~D5XDtpQKH;jc=EKs2R-JmN z>yh#T!TH0D8zd3ttTBmJjJ4YKp(P2Z51He^MbLhguua8UzsxQ>Ikm4t!hSSoA5)nQ z)x5f?NOQa_m8O*OWO5(^3>U|R$0h_1{yoPDz66}-ZuE4VoAT)W9#^>no~T{Gwb3L5mwgH0$scfvsp(C{DRWR{>`A?H`FkPWwX3V4lNq|J0n(}c=3;ZJSUDkqV2R4iy$BZ*Z(xFe}-_{nV_f z94PnUkuhL@=GM}7Oglgnp>X%t_e9(a@jsRVqles?0VnA|`fY6T+!Mf(S@mig)1~|R zg+hkJsfTkOwr;JK1((>BcUTEH9tFiCzlc}qMKmW5xk)^dfPJ*a0Wt%{7rTzz|4aC- zd>@-Sq8O1lnjy7eXEaQ`mFvFY;|i&J)3R-yFzQIH!zD+oetj|_iOtwduo7Pyja+EY zb3LtFzdO>No8Z*oV?x3v+gRK%K)^S_X4@QvOk|fz@<~qXeM}7Tu;4-zw~imVb{L}B zvX273mQ2%20Rz@gSR$bNzCxSp?>qwT+q8L%^NY=i1_*0?p0qp8dcouULw-Od5ut7m z|Dpj5Gw!f_>DH^ku_>RwHW$Bqa*;vv^eXljA<#XXhoBO2>50Re<$~c+1myPf>Bvn3 z(g)-89BaJ0wOhkR{C{KBShP^m)uKfa8mu1c;D;j4V&!>nz~Fo-Fk*)7E?2?^swGbm1PNwjV>5|B-#Z{#1!r0G!pRZHG0ukuT) zMzv?bKB|;^tJLS9ENORnCaYee#XIrdi3#s1t#C893KbtF(t;w32>r-kWqdm8`>EX% z;U}HQXxH`P@{=9bO;^$Czj-lF6>aUAvV%akBB#bFxVTH04v&KMkErTepZ0kbHm`}& z8eDuM7kJPO|QL8AyW8+}3-q*Z}a0r_p;+b;=@;(M|i)elgVOr{0JOUX9K5 zyv2lgA_QPh=9Wfgq|p%)70x~7r!IGY?jXb&CE!$;-hq7eviV^o^naiHG;2r?J|`+3 z=cPcBjr5+XI`Yk~ep19(WNRr6>L*2LmwC@+HO2`;xl|sFUH=9_6 zw#Cmpanh)T^hp%%(b^_hbJWmEE9}+u%d8`8t28J7$`$195?N=j*^N|iL{%b$rIH&4 zym82hhUQ7%98f7WvxG9&@H*0P*bTeb9pot07Zi7a4}or_dNBFdJzgmbzVTS2iQ)xP z>jJs3L0k2>!?yvjSKX}K$PN$q6$8HZ>9tzb!XjXR;H2pZ&JJ61etFEzpi z@l?HEHJ}c9dMpABCJ!-7s5ye*93u=99^(zSweYm@x;8JI_hZYs2R(2hLHmBA%UeY31BMP|G$e=o~>8UIj*$Ll__{nASz(sls29 z-Om80OS$YM3!kRGL(xC2N9Ey)OFQfMSfO;?-pHWYM01m;w$Cfu)HVh5!lB4#Q#4VM zr7FR!>t2V9h@0*%>UF58)#lnCiM+O^p1lFw6jyFaK`#_mvG7Q}lF}+41N~3sKrFnk zzc+Ku!s`(!x`1w#}-I@v;OkzwB#5?1!dql{U5n?GSq^)VWFJH^X-8y#g ze$opSNw*%RB_d5{UM$-#)l|ajAs#6|2qOrQZ2z5S&&C}r4bMMpP19x7oq-ClmJnen zn`k|(4pA!^puR=5jdtC#z5@Zb$pw$eZa*dTVt5ktQgbXv?ugOJk(`osm!nO`5^tpqCXs?4){kX(s^N@reKb2sVT= zT6=vY+-t??Eq6$TMtcXj+RMI6P=VV3VPq%0jr$k>)mJ#zQ+ejv- z9yOVz?XiTS%*%Nn&b&^p2i^tEX9e{$!`daj`to&Y!5qxFmG-`kJ9V=y)Pz7i-|d1( zkXNde*K##scyRPUDIVk_%XZ+YCU;SIGRPr$BgZP(f+VrmkN1p zcBv=P10-gNA8LMa#$JY-&~@<2JFxJI9s-4;?SS%P%W#Hg9wGi{TVHh*Mk!nkt>g%E zRCVgh8_C*P{B`A2Z}W za_r-5)`^05{m=0YFop}?zhbqzhlbiK>dS((9G2eeOuhZe(vJ!l`-}NI&wt^TK;@e5 z$_t@QmFevJ?iv_y{El6>YcGhwWOqaQelUDYfq8n;%$lLh8rZLQ<4S4bY4BaghITwO zBWfPam>5|ajB`@_v?7dWK(5bP^R&g)q|@raE<@qBnSoI4rd*Svy=ahe{Ywx=LdrYw z_ZOb8OtQQ3Op;|pS05|V8Ok~1YI*-`3L|uq2O|6Ry>X>Wz${UZga7G|=6{a#zFxt4 zIBG%eIEs0L+Xp%77=!b2MEfKLq3Uho_@4Wz@e+8qdtI)Exiy4?O`1YWFFmEs{XH)3 zPhvO6fJ*1D_Cozfb&H=h{fs?XR`$Z&mM&WEgez3B>DP{l5j<8!1w8#le(V4Ig}K4e z9g51CD#+=LopF4%Ue<9?>LNJ%`#eu>cN0*4&)2ekvlK#K{kUl4T1QjW2R{HS-4fmm z2FOtq`EVHW9)LDbk0_ha1VUMkMMTZ3xX7yK@vDnnPToswIZkgoQ@6gg43GbvN(;zY z;to%M#Pi>%MD2g^P#=pNEUgkVgl%Q=G*Q1&a?p_(bGt`RP`sHe|4MZ{ttc2{9%#jJ zHIy{h^8Uh8>@`W@{ZHK02T_!y2J&*bj}!wd5L0FzM&+z`E`W76G1dmJS9pIu3q?Ru z+)zS3-}K5QBKgo)6z`MDHS@e8on5NbR`uCDCno~pvJrFE-RFR5or-|X9BilZy}t4v zS-Rkk?CUD1t3B7guB2Hodpe^-Xv$O-I7(;traJwEO}^+2i!(olRFyoQnk?sLFPG(V zd+EEs_uezSgvXLJqkWxg_!XXZ?j3>3pgOVq1JDe2z$Iz&1o&4Y2nF<^HZ2J#1P6ur-sQ zn-b_5%*yVgJSwauMxvtq+x^qJEWoPyQlB)G4uLfaHUt*d5YawzCn{GadR_Er+)Nx@ z_VWbXgzKdb1P0oUQMe&0qRGkTrh4o@q=f(Rn$P8~VEH?CAc~-2&NJ{29f)&OpV#e* zA`|A?_3f+OdcL+#gq^YDMbzwB$@}lA$&^*{`0QMaI+<*L7`Y{hyFmF{v*bV_aS0k^ zBy_d(I~$sPu?9w0abcZXARuDx$N>)!hps=@fi+ehzD4_!)iu$p<9 zS_i+!%}7d4HmHaT;ia2!L7V z+WR%t$|LJtZIumYnpPLV%ilcnlB!S8|!wBLCtIaJ@~{$yPB_f%Lie>zjyqO4AFT?@os7&4dbl?53$b(g z+gQn#Ce2R##nFYi`Fl>qOE=Z@YqDfq>a(j<;jM+VqSERe#b+7(#%uUz8yewnvk}G*BNlUHAlvJgY1Lugq z%t~C5IbO}+YRp(XqULatZ3s@usoXM%lKV^vW(sgXwr54ikbLr?P)+;KOp)!*zHt}K zsl{89EH2JGYVFPZNw|9oV_dH@rK|IS+B{^UZd8)MtJ|mbA z1YuF^`ppFjh>Nc`QBW3eS%|~@4=jO6vqg(Q3T7z=hx@9w{;`<2jJsfDC=`eWZC@>o zG2$P$U#LCiAb;F9v;C77FY~z}rZq2IIU7I`Sl#Ieiw6UNa6Yeqi$Hurgdj>Ovv`s| zz#nX`Lzq%|Os{wS30D<~$eH1JlrR;~(D;MPj}!03A-P>*a>EH$X1oNUTMubkob}4_G3zKShpmT%k^kaX8Yvf_fH8*W=(Lzu9T5>KE3!o>6pF zP-{Wbf&D(d;mcF59$E$BslYkQk`rHIMK+9OLi|ofpOKj2h#@jm zU1vpE-xoZS1vF83mD-%sZ0&}$A-ixZ&MNvdh63Bx;A|yomnVB(Xi+@0A)c@_Bg{G3 z=43hQBuD2N;pU8F{zLfWU|%YIcg#k__q8c&Iu>Jk7HDztqvVj8<^*!CwU=j-gl;H% zn#2Dd`MTPQ5kG>0VWXga#FQJoM+iGZs%0cfR%k~m$6#TzM&iMM!3(Ktp_CQU5kEz8 zPP$OAAfEZfp(mxSM0;bN!_{01GEN2#=j0fqPPL&sTy`pi9WCgTFQoZq7>Iw+d;>)& z@p5!#Emg1(ZVqRsx>)`0dv5ZY)>G<$P=7~Oc;e}0Eq`_DYNjq9*8zQ);OzIa4ybmc0~%BuY7cS zN<@Ahe{gih+&&4fWYVO}I^%$Zg}nk|6Wx#m=4GXN--m0)^RxkdYE$8(mv-Ot;0mJK z5l&yH$kOFWueat&IllYLb>}z6lpRDfO3c53R4;+O&m`Z!pSszg9+V!QLYbN1hZ52h0m3ZgS)wI(TXYzm(xmjgu*NNwKZZJM0XlU8p zWHI*^I)^du5Kf`|c z{pZ|z&;17ubPb;9mSSp~T|UMFMr-diB!=m>op+vw(Aj(w?BI?NUkkg}#~IM^{Hd=f zbprEYkBdxlQ&)Dx;(>Xmqbtl-& z4K5`SV(gcus6rs60-RgvtAAT!+c4T_@KlAj`mrk+0GX4==_S$S4EXV@E5eR$XUXwJ zll=v7JI&g2Cv!xIa6~6FAj$X-A0-g45d9{ShK+WyboegD@Gte=*lN#JH~*uxeC|G@ zq_-r!=8kVqA}65M|CE`BVEi3iK+XcTGSehaIScv9^?iT;=so)blnxQv1X+u0chvE>{cGr)s>~tT}xKF>gIl$tpA{p zh5Qa~&nu0xHv<8Vr{{^anrEJ55V~!>h)eZGzXknUd-{ecsz$e8V3P=C+zFuKH(#Z_ zAww=y*udhgeFQ0z@Ztjqt2UI>eKPOXn#{^8b0F4ER4}k%= zKJq>PYq@0$o5+Q=k%QbS`NH`#;;5gIqf{|e$5m7b;!i_ehSphB=&Gfawug} zm?1Y&O6))kYO-GuN)~00h>NIgOkR%9w%j^CFJiT=ae-st-6Vgzm3>1=7*MRf92_-0 zZ(=p3xAY1=FEJ?YetA7t=(~Ic@8RIWcHSx5QM7aTd2p=?eJFwP%faTR@7J7SkY3glHB=KTmBcceBecbl z>Cn9TE|}ZPg2C%b^SLpFPH~G(M7U5T2fEUt$^r+0@34;qrr=qX{=sD#H{4$Dz6`hH z(%R!7HMy>=m(E;I6u=)%V()&YY86@)ge5Cz!Mw3;1+Vhq-xqqBXFy3zgo1-QWoAYC zrx)s=_cdY@A+P=sQEIIT_>?Pip##bLF0kG|7O}U=!&(Iwc8AzQ0jNf5O2ZxfA8G~wC2h!kRhB8U~#+KO68|exfiX3pR-S@PFJX^ z;DFOtQ%vrDJYW-ErDy?Mi8{!coR$jLmrheI+gIox6=fW33ZUdD#jz^E!Rw zl18K~P-$0Kaxa_8+cQa_B?5pUv;G~1_o5k@)=kHo8+V3>pDhoLcHt4cW!_EmteAh@ zqC7*ajk>6eac&Vts4!lPLlGfMfr?)1Va0F~{#@mmnU$HrCq<(;w4ZJ)mLESUM8uf2 zYB~&m@G?HhA*oDsb;QT{S>&aHH4AdEkZ@UL>}uj80}N__b$()BhI4J*!NaD0vO`GQ zEqCcdJA1gfQ)az@xX??Uz*Ockg=`OZjiVfPo4QI;6pQzJy$t8GIkY$Dq^_gDO=Zo` zS9jIOI9wGaU>Gof6rP^)Nv|s?tb&xCQ<>^f*=yle?W+}j~>#&0O4HLe`E zOCq$Gi zO0ATI>jDvlLbzyfto!aRIZ)G40|lx(u&MKzs@;SAB5e3p?c_Dg-UBgao|cuPo<72c z(FbqgtV!gQbS^0 zJF!XI`I0yhZ%;lMtfpO;tBj>0;r<(sS|LSI$UJ%5EWkp{0S3f8C!R}_ZhT?c#BKUm7Pn?CF&sh(fBNf-Uv}L{!W2p5i5B$WgLtCIpo=W<}nizMAVkJjKpF% zUs>Xb?wKyyXt@9P+2)V+A5DuSS^X3N-3nJLj}J#=g-lic;<*jL?yZKldb8eCksI|l zPa!nXpaLUh7N}F-&T>I*l`Mp8kovJ4n6)iBL_cJ0oqqug|@VvPer9NY;BpI0w> z)=*F~ri(#Bc>feyQ+sxsq*hsKY&e~~W-N!(&_?m0Vz?%|Z7k8uM>0?8HQNK(w;as1%i#1{kjK(x(|m&`g`$%mH8eScB9Y0}GXz zN~w^iCtI1Xomw}}kl`_(*V(gI#7FB~o;V>HKxn~uFZxBU@rjv6nO!tlI_34C8J5E* zrI+FsyLkHq@}hU)<=3JXp#v;_ni%kA|DLR*spJcWEC+D$sMjMQBAs^n{YjPa+$xLt z+i0gWUCZwexnJJTjeOdbZld4s#pLPVOPR2OqDXQO8F zj`xC9qBJzA>D&Jpxv<1%HyfW5Q{Ddahu0-VsA zTi?AS{R;~2NRFwo1h(^(wC1-MR@;qXWU(<{25WBL8F!36izQF~3#Qbv8mk&8MLc&Y zcIu-V?%X{M-$}V=MQ(l0#!^WNG-J^fwMbJ zJ|&Ewv-u-;T~Au`1u9e4q-kd&Dl812^mJI`s4WC2vvf7AIE;!frF9iauy=;! zkzMz|Z$e5iW1&g{`X=o6#8eSPk^>a1T*-Ayk?rk$>nYPQ1hL@?0i^SNbltLTZ|Ggt zT89Q~OL~F^$|fvCGujc$)d3U)ETj|s^jo=lkuSLf7(qSn+pM}jiz*$tC!!1`Y9=<_z#H=yL!Lw z$gG{~UU<`^6?kucmY@t@iO7%!b{=u6D^Q6s(hRn679jP<%TITAc^CduqH@7vz8dk# zeGxZw7%KIIeeSO&n$_`=q=b6d9Sq;ayjN=}bOa7s?Y++tO}v`UpmOLj5o|#~Z?HrR z1Y@>)&5{6X%WNcRZtT=to5zFm5{?oZX#wiQ{z&l33?7Z$ER)1jAB@7qq$TnRVZ${i zaeuW4&=?U6JE2fytingelIffa^2hq5bx54dC1NT+l49qeTXzF#KA|KEpt@p_LmI6M zt`KHfeDtI&mu-nDhv!FCUND(48)86AIDpm8KJ>*dU-5)fcQ~H|TN^D65Bh2MQ+m#g zxUpEk{94ZPR}~POfR5E}EA?j2>c;DHJ=kv{g}GcmYH54a_kT+vYXLkQuxegDJ*Vwo z#6u|*_2RQh1#0fu?K!+hDKuv#eoXL&RfU5OoUFtEiL!D3no36(57RI1lY0Y_0%K4g z=YQ*f0Usfpe1WRUB}LxqKTNz(tzraODnUVQ`VAVt_ zI=P&d@GnVlJV{cAkSp{$3s$^#grgn|U$RSdmXknEayG{3=V&Ch*W zbXv75C(eruZWKS)0}@(jmAF0&YRwV2dXz)qSB z_h&!5&?H0?NF4kY{S~nR9*C*J6DfUFIH{%kYl_v|yalfiZqge9+REG_oztcVKSvS( zQHF!fnj$C0^_F zB?@B@k24&t=pe*VD%g2$WsUa3NK1Qrn0S$2>&`J_9J>@t>leDAyp&H;VHW?1y>!|V z1W>?mRviKJI7hlqub41rHL*1|D5pp2jaq;2N93OMEXIh{>hU zkFWwJ*ZN+0kczQDP|P&SFcgA}k?b{J_`{~#hpx8RD(2g<(u(1t;3{Z{sq||y1NDE< zi3ZM~#S9}@n?O^|^ko)Hy#=PvF=?r5%#)PbLi`=PB_QrhbRAKM$&g`ivTu2zhAL$roQ zjk3n0-MB^-TPdygnyFP6)lK2I7b9H58{y?u^mYNNzt1B!^bg~0twsjK=Xg{Gz20r- zO*9YaW|vDD19C?Dmgr1B=g1IjAn7`Tdv`d+eflT@>!p7Bwo8hL?SC(WOH{9!RWb3<7UgrL;mBJ`*zl%IDk1Gyn5TG^qPNX)iVh%~SJE%|AEkKxT2&>^Mxra_ z02W6f_z4o9Br=a)Mv zyHgCs0OP}))T4XQ;xJie1jkLAWA%IwlM8)(W1Xg5WNK{~^{0 zft{5K`EEY*oS`KyQ$Eb1Ux1VHNvz_Hfv3jYiYknp19l^40kRoZ_rLabvUa#KD!B3!Qfrw^;SCoMI^Am}%Ziv7OI z^woOagQ4%0ZvO7zK%PtXv5x5l_!Zo&dLT0=%qsW2(OXh74Djfi=>|S=(f}mGo)D$k z7tMS__HVX(cESCTLl>4urW(e0WgmToq+zOMErO!+rFXN^RHld}^%03Bjc4#~0-tATt6BT_w~SjR~ZU$f*& zo3}&6R)%``GhO6rsA*|B4xTgP*~ZLRc2H!CdJWS2n4Fy`_=Pn&rmQkm^IWlw+Nr4A;oQiaRLxMDDs2dlZsAeJ)IeU(|G<%|U3=;OqJ#gVvK4^?G2 zwJ@f!Mh>&I*F*2ln8ZiR_zlg+sJz;;72$$(5NdA6biZB~AmC>ZhCdtETODsM6xmqu zV!I91ZFf*wgHZjG|F9FT{vC9b1my4iN8-S3Ykjfe=P-|Z2giKFj|6rfwPSC<1`}G~ zw&P%0llz_~6djDZ=8p-)<&@U1$!`A-w--zhP#7yH?s5sFNWO4!m2d}iU2KbYWDz#E zo&F~K1e%LL6O*qKDP;q~{VGd|E}mDiEnCFb5m5;6s|(Pz8jA#s*}ELuCjG4ys9m*r zKr(UZ@?*B1q#^~X*SDM&qbCKrT_U6)UIT3Q*HVW4<(ytb2~zZI(@+!OuqV;fsMesLlC0#^iUAu5~LiH z=XJ&3c&dZ2ti&^`&E^be_@BI8OJ3eiYn|-uBWN`w7pB2vY_mJfHlZ|pnJn#C7NDA7 zvV!X0AaXh~=Y|UFEG7-y#{G9KRdag{r`H21RyuG)YI(}0_|}gra6~j=K9>{h3n|hm zLEj4Srg4~W(|ScIjonXDn)`Rs?hXM(vtf&R&bBdxb@x-agEAuix^;$5+W7wC{MNwA z{Aqq*OT-P{(orXMS!L#;q~GhmW`74pX1M<=<^iabO>>;E`_H6`Nvx;HBvfJ@A~9~-cb7iQ zxe1Wj;V^Hxg&f1AionTL!Hx!^E1 z{mq7hur)GXRCTc16Ah%^m;E-3pk4@BHLEV-dKwyveq2Iv#qfJ7Z$Ps^{nDf#MsAWE35zlFTv@m4OK)3#_ZDw`s$K{$Yb@G!6+p7D9B@ z$HzzF^nz**l+9Kr^z{CAAw43fd2jTV1Ez`=McF)UPgu3MT$-L6Ybu4GWkDr87kn7% zFrOR4;o|CivlyWwbenzuE^GfY!!^pD|6SjRPnRSI+lT@_y@9_cTn~Ue8kc@Kux{!j zsuo@Vx^>$){(OVtsAn@Z0|v`#5WF#gy&}mR-7We47^My9WV$yxtzqh)V3H|zz#MS% zACI}Gy*f9Por!RiSM4OiIeF!_s_OIl@qB!VE^r)nkDFHPtR%QS0iF|qlVc$dEgsH{ z*geBFmFV{R4UL62RkTCoSf$dMe$jF)CpjL9p-hm!l7~6blYp24tF4I&v=5fA~*-Xm>}z;g~^2 zixh~f%aC1;yQ^^%w38FLr;EK5&N4nFkfIS0n2J%C$Z_z*mR}O0`I$AmZ<(5}kM20g zmxOhszCATxs}Gg#*Y&Yj{nVP8o{*T2@|a0POJyxKNd#6cy@7%xWqqx4x}>_5W0eTM zPr=P5>qcY}Qy8ryym@WLuhvwbXAKlX7Gc2k<*_o{&Z_Q22mbeOaWO??Iqf9n50m@V zsw3c37)32Ezo2mG@g@vzjHw~4!Es0$m~;*HnN0@clalq0Cv(~?*ttv~gk37md7Rt;BA&Lt zz3py}F;L%DPx4B7nD*!%^YfhhBL_tOYyZ#zHSJYg&htAZ#lzY#rzwAo-WIm@n|qu- zJ%pC2>yAY++1mrOucaFU+KES<{qP)?_Wp5W>qr6vC^*b_{wxq^K{V(gfS+48!Di4h zUW8=IO-h0c1)#AG8I|ANz-D|ZNuYgC7iH;q*7Fk^H&)r5?V!h$|8q@ROQIRz&C02h zgWTPG6Ax$p)din=TXKenCs1KRkvFjyoJ-0uVt0`@Fc_{Wd@>*iaoaSnCt(RvtbA~7 zZv9Cq8KTPjWnlo$LbUj@8Z#pu%}}H@M>I`+ln)cM{-dS78f9*A+517SPjwTpnk&&) z;V0+~8<#p5hzCiFHV1PTe|)Z)QH37^@j^~tVDXaziDtf#6dYZ`ptSn?qeU*)glZWDWM`)Pqa; z9RMxyO7#7=9jLgql&ELI$_yW{fp zN!0~sD71TJa&8*xXp53?T^0NfQ2?rX-^kvE`wtZT9&Ez2u@zO#xlx>>LRhr_lB=i2 z)GM6YhD&`Ojr^tZ&Q@L4nOUB@w4$mK<&POwh+gn>dNE^}28>atDvu0M{NUBj)pZeP zlCmfD(*>Ie-N5NI&)eCgxP4Cpj-d*6_H~R10xLQ1?+S#0WZQU1@+@sigWQMQbl)T(g+${wy*la~P=D8Zm4%c;aBG5#pw_ zosRvo6qLM4mFuQA@Qm3i>>ee*Sjn=By%0FXn?7|iWm|%dCh`e!^^@GsomF{4HG&7p zZ&@>L1=lVrV>Di8@(-BGV@VEATDXd$YBhYY0ZMNFSYVE4=(iH#ruO^OUM)aP`8>aZ zgmDHnYAI^D{DM_i1hziwGqs$MfUe11#=uFm>y!&U@1N%eQSI>h2r~G*kZJ4KnsS7K zc2RIJ*CNUd6$Ga6e(Ls?>EEZE>nN$Syx-`@C-1|bCbRB0*haQcJ2oEw|HlLplBgGyiM z!r)>cU>~RJBcu~7Thd|o#G-!kZ}!#krT^o{qnGWJ_KDe``o;cZ6N$h|`uRZ>nBIye zEadOc-0fK0{w~1}bwrcZgZiJHS@?MHSf!cpdO7*0CIvZXKC}0ie>~K8PyduzfLG@1 zovTkg@fh+dh^o>qeZL(e;}qWwetmL{({n~FhGlNJ^QOutRiLHP=M{4KTd6L&|9q=G z1G6k->eTs~=$>MJy(p|>jCJQufSMVb!kV*>%ENYl*}R;XZz#kQNQec{7ofn4>* zr-SR%>$EjzqhIZ{ql3lgjn*5q)6uXkI(yFr8cV5D-Eer84LM3b!n3H?Ykj}+LEK0G z;0b88vvYE!?-RDA9~#}+Jj^SvV0WscfJgki`gftz=0HBL{u`9Av!0xI8$YYU?7pJc zy3zxQl0X?a9r@w*%$IKFacxU$UfeM)duVDf4z3d3pmm!+KB?vV02?l9Z%)4OR$-fC zJx(#g@Sw_8o~k=u40dxA(f=XJ*%Rb ze%t9IA*Lb-$tvUL%`)f+R26KUG6a``7GGp5kIhZTZTdg1ZEhvqr?*Y&juQq znRWTf%$-tZ)VOB#AEHSY&nBT>h&*js5-pV?B4smg1lts2G1opQb(H_LL+9_ged-1u^Va0RCJSg< zbA?!NB~JWJPu2?U|?O% zVw98R>0(zeKvdXqT)Y}0Q(mXo#c5%`$@;VK#}HfD*bZex{oQ&8v<1|A3$cbEdw&;#zn5!I9#nVvnqt$S40q3Uu>5x)Vh`E`Eylc+Q+32aki! zm4_}}Vkx`D)YvmNtLJO~6mt;x`-Tm2HdEpaRQ)TzciN88%I17-icCyOkkWvN1}V_P zW8o*|%rG&WUfei=6^QxdtcX30X4+X&u5*uJ;9zRaQ~wq{W^7z>QP^C4<=Tn&q2*nB zo6f>q8!bpH;_~f|t+<9R7>z^`8)4BZ^A?kMs))iO95e-;n*Wa;WNX=#AE+AdI{vfk z+mGXuS46j*cNkfb)XsjwDhuy)hvW*SO$-PmBC$a#YdP^7$w*OpKBez&4CuN$<1+d}eg{EkJL0X0)l zwHARUnxE1p9m%Vasfm6?azd#e;H^g*zz5 zUWH|dHn6jgzyPpQO>sJyZAMQwR%mMU9W2aGX${pLoA^RT>=D~jC5*gQy+&UZ;JWEU zLt$aV3YAzQ@rgml&!uiB{}we9g|PW|?-WD^!qa75iO*fVf!MWAWwLFsoZIE%zVQ;U zREq130UU{GF9H?s@3p{=o!gJI$pS2I@D7VZ@^wia{#yC;8C~UOeC$L&iZrXCTCMvm-$i(zkY&^B z86|#P?DS>5OVVR$&sF=Qwh-WW40eOXsDCM>>1QBNohkr5xQcyI6e61UP>M8Hztaa_ zlzI#PQYMj$ZJv(0mZe9Q(62RN__@O@=|J=X<=HRCo5Bu|d18`RgJ^hthPO*5Rl<;I zMY;xeflaWyZ%~u6+piC2l~;8n-QmZxBUs%(_m&@6#TFM-^uJMa66ZYVY^NU^V8bnP z_+u0thv18jfgwRVNGx$SHs};sQfe|D-f7is>)b-OZ7xMNti*K?-iMEY4FPvHKfIxj zDM|6mtGeTDeZsqW;Wpb9RJ6iYCojVet1s9CJQWhkp1u7HPiE zFtnP>gI4!P?;odcCt0U-b&Szm2vYY|cV~W^9}*8)oNUm?uYXMJOeZFjW^Kc(B&Q=; zqysy_kI;OLqD0Sl!QVMRJTv-O>NEV!(9C;DC|4J zgJW2q0Ay*8tFOY86H>0wK`huV*oBJ{_d80JiL>auh74DfIpw;Wz(H?^@?;MbKO z`3rA%BI{*vBj;?PlUQ*qjflVbJ-MQvX)h4#Jqrs#w=Won_+74Z2r9=En@*6Hd*6Yv ze13H|dinmxv7I~o+)>frsae*KB$w6DhSZr3(Cyrx9Mu5G;tK#PUl5U=pJ1wy4AAYz z?ho;ynx%-0M`>7v`m~AkEf2D*#{2U&6^PLCM-ml> zzHbTx5l#4Y!Xn=`UzQ^eF~vnaF&ND6W;Z+0}3lOmxPPx>&+MIFC*_v6k)NhYpRb~B!44MM&{}`?* z*b@tviZu3WmOmGO_{}HLJeCL*b**(^%ZotH3*uj8t&@0ZJR*7z`er~3vIqt*^Lkmz zEw_V+>3^Bc z-`xNzPlg4P@jV(Z409G6!ondhgj;hu~CyWXE|F2 zC~@UWmx7kpg*WK%?4*_qgLL}lU8gSJf_HORD1P1Y7lp<$8t>N^J4zaR(AP-hv*#jB zi0}E7=v-@E`VMG+j_Kq@hbHnOItB}(kl2wRfb>dH)VXdkw7%;(IAz!sJM^|NoQTmcX0P!j>Z zh=FwB;1tO%Uc;kyzp2#mP+;PMu0{&Y4jf}P>3K->+*W*Y%hFDEF!(Sp1aL+u1Fxb! zLVY(Rs&JO?U%`L48>~aiHKHtUC>15EV2Ot_&STId(?Jx#PMc6=fSuL!@pX)9NldI5mk`LVz&iXa*@L2K(o+P&I+8e3ng?A;ygcLydeos(g;mh1U)_AE5<+|% z*lomPgF)cIsd*oJ3GJ86M63{+<{A;MncyyFA>GTUNwL&*~`X2Ps6OC*lwyI^-+a;i8)`N7u@0JPU0`WE><(l~9#n z-DLIODthT6tC+%OZXMlzaNvzZD5BhdyXU`hs=2;MrC2K)j+vDw1gY3HtGB>mOXlWYVgtTD zivwwu=ohN5Q}oRm`=V+)7g+bkzM^VfDVlS(Vrl~y;+vw!_uQD-!*~_}q7~tO&^#u| zsytj02cI1C)|U!r@(<@>ORX+T#QQ4IHn2ZB@*FX&B#AqJ6sQka+H6Ogx|JII&+R84d-`M70rNxbq>jH{NpE9 z;WbEA-u6~wlCFW^G*#FrB*J6ycOsJ@ZdHuejoI`AlltNj&7tF=lB+&1>;!SEfZ5=b z9quS`C*wmeokl#*i(IZsSRQtUv5{QSTE#BiMJ+`sjjjm60{}`d(XM2+VqHLP@9;!V zUJ(}M4CU3KqaTmMdWJK+-DZ!@{d?RY<~bMg04{romP|-7Q;t~+edq_M<9Bi*JdnI7 zY=r?XFnZ_ksRh1wg7wzMZjBq|$X$FK4{sc-%)t5Me_tiglN!! ztd9QVs_m)phnY`ZsFhYcO!zZ9i9-G>74noiXv|qp_b(qgS$g5(jG){B6Ztj+FN;Qzd4RhW18Y%x~Z1@zaC<7yB zPB?ciSLdD;u)v-s*H=+J2ZSfoBWtELZ&qUP((MvUm!WQ76c6Sjc2R{2_ z9G#pPBfZp+I0x&&uuxQdUc>(#)goTPYQQJCTrGgz!t(KAh)VI?zopa;iG(#^D=MS7 z?xa4R5v^(<-b&1f)T!#!+<{jqDRZm@a%ZPk28MNT+r*ym5`;wne%W3Qwb0H(L5bI5 zqk7Z+a@xYg?#;EZ;m*vVN%N9bO@5AB`O$<`_ogzO00h1TCl;dB@1T+!eP=N?7GChK zz|^Io$a|FBh#)Aqj={V5N@>uc=AUbkR+7COpk_5z(}88Ck?(W(P7Y!Nnpk8{N?I8- zj~9VB80Hmd&EfV{79B&&9?QiiPA{DII+Vx=n2R+jv+DJe)#|D-s;j2% z@%`1X(Y@BnV{#I_#kIa*hG`bNP@;pLDd$iLK28B|mCb%BP9Y&h^FkasP0Em((Q2;} zsm-xVdR_jLryJ2%5?8}VHjp0LAP^`OB_f0>Oodbt0vCw!W`R<}+x?gTe0oP8UMBUp ztWkLp=V>$!!!Zc=F2H4`kouMw`uV-46_LU{JNT%w>hhU>ZhRhc*urD|*;Z(SCGDw4 zno&Xl8m0P(Qa@5z4x=m2*&hEhk!Ud1&4_%RM+I%3s2L>Jh?4kUrc7Y}II|*&JOsO6 zBdvell1^(Edg57OrC*8qpR=-@n(sWsUALZicPi5JljkmPSt~w{}AM6|6m^`x@ z6|A7^xhqZ@DafLlNxZC`NY%u_Ah3pCWKjBZQo(uR8>wt(xuZOS!fHOqttg4;1%X{C zElgD+WQF)W6$YZf*?E-Vd!b9TP{_&}9;m3LdB#V=c~KVg2ST_^6HFjRJ7sB%hB+Y# z@b=OJ6Ms9tuFBk5#^6rqa<%1djhpM0Uvd;5w9@>$z0F5R)@gpZ4M@9_>RPuVqbjV9 zJqFSFHSio1k5*KG_)@I&)JFI5yqqtTKxKlqEPqm3BA7K=T^`lfT7*>LEUZ;!gY@xY z3!bv3`6nn1sr*)p%@Md$L5;rD>%CC@Th}E~x<@5E_PKwZwWpYY@FNj3*HwX4$mPtT zuJ2Q;<-pW(_y9kA(+qetl?biZD+HLZ$PUv#I9wm^%eVm_uQzWXONf^0ZyUHHi?Ds> zQX4tPDS)a^rH*>&J(1_0my3PSJT+G>5Dec@ciS(L4@Kl}S*T&Q$NwJP3M}`UAi>X4 zDO)SsT`X1#((Ws2f7yA@7FA=ayh=?N&8g|I$lJorO8)wX9$7;09FboPAa;ugN?zP_ zD8p}JtN05n1OTo*NO@*}_}neaBAk!%TvcD@NZ&}9={0KCPf~@fWmANFmL=2*^$`9x zTdkE6<7i_;|CMgW3?5krw1^kO;&Q(YuHi(LMA0x zJN*Q9SB9Z)wbPG2xhXSy!=@f{c^lyMz*L+JE(MdpaE{>Z1fJ=aMrG=GzM&3{!PO4( zvuyh_L8m@Q06fO3o4u@%}m`#1UG;yj+XsHyw z;qxgGpM!$DCq)4NyAFFy5gsQwOxVRZJ#| zHV-(0qve0_KFTNnA{tJQEn{?La*|na5&;;pyre^*KUn%|s)6K5$0*IidSM7d`)PaW zM@%=_eRBxZpaGpHDRpsVbZ8>}{KMj#=jG%qAfMfd1a}g^IB?zmxKrr0!nC$q$C)6p~8YwvHFJ zL@DutpBC;ujoB{Y*knU9lx3}Yqm}v%V22(47V2Pvxi*eP$BCvdW0d>wX1du)qnhVF zHWC-o+wyMy#o_e4;o(jlzoFcU5_jzW){e)=X@=+(Ofp*SHU`A2%o5_OR>e&uEu(xm zv5{MK#`9-uY$Vw3FTRisf;ho`Yj=S>@y;G{mV@u>Iwv+3qfCbaa$Ss7F;}vBD|;Iv zY;Z}pJRP-Kli# z+jv3FUxR$6BOIRi45Oi0uG}&A6Ms;tL@s`;lnbu7Y2p$fp@>;PU$A>3Nbg=O{zSq2 z-HP!MK`Kusu+c}R@S^ka%sYcR9oh$9+GDamzIvAEeqywzH3@^*p+$}8Q6W&fj(A`4 zbH~Bd`7RVFodlP;u$eB z#l?_nT45ZPU9P(W{2RWfglsrnNMF4KT0SWl1gT=w{x#(-&H&!#vv;>XTNLti-DZ`kM#4G z#BRE$cbI}*Pe9pqFk4FGO|skmVxqt6aFg0i$HmE>z43%0UwlPh?eDT=t!W>C*TjPx zx9Z~;X0)Y-?!}6jPACx1~_pF9{ogt7obkaKy>nCnHL zDqLFY=)!Np_Y)OaFFlVvQaM5V($h{Fa6@n$m_h;=+(=k3)+VZ0CIUI9@b8m=k^`J? z7RD#Wn|P!U1CRElmB%EFXT;OLeu3r4X&4$hmz4_WN{@SC47TQXpyjJO^m0@XiQ}K8 zrzyq~wF{l$njf6FR((+C$#b^~x{a^RjiI0u%vR-8=b7{#qB|$F=E2hvlXpCdk~f0J zetp$KPl|XwIcXHY5k*4TbdYhigLX~=YQu_Tk_jqn70@YZdlm|za>?H=kiKA5JQDRf zy3xscp}(QXj+UvkW1RUioMVt6H_Cit*6h#cS`kEIZ}v6}Le;;<6>Fpu4-+v=2#b0r zf0<4w2IKe zSq(htkktR*XbheK$%5ua*xxbnILsYO!CNYWQ-l)T`d@}jhx&!s9YHX99*|Jw@L9p> z_k&N?paKBBRQ%Up)07~yX8AhQe8L=J*{DC3$ho+@Sd^zK!f5+%bn63UupPoO?THWU zloF9z`)oDU(m>dhPBx!+uyiDu~6KKgy2xLP~1}7p%g7GuEpKmgBFJ%!L3l-DQ?BBcyWi~Z=RmL z_u2n*y`S@iT-^6$&8**=kpzsad%h_Xb0?&QMMW64#5-S+$bKX6xTVJPF9?K3(ByHx zRt@C$4ykxA6}xnb{;UqLBOUJOvsbkHJaBc&vuB!T4{V)F&Luvig;`bLqqs}fu=O7u zWBCXvS4yrMbD^<^$^bxXt|uyaqd7ghWkyM1D2JTH=f}-=5?MrvwS{Kgq=g%S?)W~c zTg!1OWyko4J&M+{jQ*JIxAGN#-l$RW_5c4j|3Os!Co-kVaEKi~Y{lI!InVEfIPx!| zK@T68iM&~w%60Y}os%eem&4SL_b3{}iYP5aSFGRrUsX5d*J?E_B@mTt;$0Ee%tl%f z8o6TF_AicJ1I-`3&h+h_i=}zZ$z|(i0JVyh@TcD*>%}3JgH^G+Z&$zofkLIg4`{QR z)4(Qwi+Yg(Dk*j2Cz(%bc+3v~P(E>_oy_yCuYQfui;FAWG`-j4e$!s)fHCKd6Jxyw z9fu|WhEFW5Q< zbK~ql0af*bj`2w!Q|93JBcQz3ja*1(YBa~K8s zoh{?W=%P|LcfusAJGnw$4YW08Mi}RA1${5?V7Kzy*9kK9s#3m^fQuk zbag03xot zckE2zyB~<^N?Bpmo-1i_FXuDWitUsItM7-_gnnCDyCnsI%dE|Tx^ncN2mxx< zr1@f@zlXUlDXv*Sf%Q{roYA5}kPmbDugI9;yMx=ys3}yz*Nu058}TqN?RPD>bbYZA za@uFazcnzl148Cho#?~GwJ@YVW*UWRMYwyAvVv9INb+7*d+LU_ntd*d(A+C{A{l1D zJbKdB^kNO+dEvY^+kfsHc9Ih@+SQ%)p6%)M&D>`#0(uV;aa_bFkbFs@__mK4{3i-D z-G&Udv`qQBrdn1mAi<)v)Rtj*8*uVhd7Ag!IdtlnOT>QmPCgO+6I}GA(012xZsb@% zSUM!y7>9zN!nP+$!_Ue$AFV|U2R|ti^qTrR(bz6DOYr0!fk$(j;YL0(26!DIotASZ z;iBp_{KA_dtF2hk{>WWOtWe-LXPjpFlfbAwsa}upsM49U+S2{I1AhM}8-&6F&(S7q zB;hslG>hek01xb~S^xW=G(;JUUNLVfw&(u1XbA&ut(k~H_=NE}$2d|lGOgDb#qn<| zVBs5U&v%<~2;uA4#~*<@A6#%Hl<#qtC`C`d3{WS)BDESqM>}X9`gUjvo^QWBUmO_< zDJ<{pzC%cMCor+OZgQDoF8A!Bf{mJ|?2l>v?plERPr8hs?O28cGrf~99iO!&I~Irh zzZU22)2~y--!wEJ(Nvuqn?1ZUefeYS{ug=5AWGmC?isDw3zOA6ghs# z7${VquZGEiR6+`Eur|%dUx&v z`Fi<8FPDdTr2M+e_vV|}OB)RXo5g11`N(G2?|$tcwgb+;Y~4I5js&(+f&8qNgzssb z<-%k{>KDt#Xs_#%ECg5gcF`ln{8IYZ{9!)&_aB*D5l~LUsw*Gke&O!I!1R)oF(+66 zCMGnJ&<)F@xK30aF7Xk>NB}L3@ z!$-Hm&h@C!;LN>A!(?435!3)uhEdjUzVf$p!^NCUprUpi2N}N&PTdj&I?xa1q+12_ zvfCj#|B*Z3p;3)oI%d?)Rw;uW^S?#8U=FnOc%^$oGiUf!pY5IPU%ji0xI~u30)%SM zlbTC8-K<5u8>2qXE=gj(9n5=SPQQXiW$zWSMnhT^Dj&(r0s2!45*snbr%UP@Z47i1rqP7YG(7OfSWKm6^%utzl4O2;Izn&3E`1TXQ*kTC)$6E1 zWdn1L2A(Fz7zZmCt`S=4r83m6fvBK}2q21S$(y~e-uTgy%cyK|Vbg<0{p}m&oR(y> zP3=PT2?ymX&tJR#HZFANSm;-1*fqjem>WqdXRKTrYt~zV>s8 zM?1Uo%UcKHPv6Pi)W2Sc{UOu{7* z)k}sKF;-G0bGQ6DR%sPxa%Hw?{6P3y!Ask(Gau% z`d_;X+;LL_pW)!D!50&PVLQT>4IQO=KnJHb3e7q$sJ!omrdD)bRhZ+zd!d4?KffKC zP^YrcKBfJx;hMgQd#s_yiYKR!FtiVQXSQ3c9)Xois^I3Hcr;;to(*18MTw9LK&Gw= zTQHhAx?+?v-q_CiPhlq0on_K+ws-e~IDK1hNW}9#=@aCXWno<_Y9cNNLN~p4RV=`A zi>}nppRQY-#HIa%fQmRB$O~fKhLddYkh&P|b-z1Us)h&1yU`nWXY?hsJ^bxy<4Bj9^lL92LVX`1e(5cL3r3n&W(JvX z?)}aEfWGy%$#1wFR#OrsbjI)Yhh0*rhdP9po_|ISh}jvsH$Er%B)Gq;k%`&K(mOU# zKwglB5WHeF2Rj`7R=}Du8-$Imf!uMfyc6XUvX^J*o8qAlcQ35wxx(ksCs3VZi{7iH zcPfrV!6ISdehuO1pTrUIR%$)$_Or<{H0LsSJcy~xToHifH+~1E;o(8pME-=~X(`L1 zAgYk|C_}ol?yU2J*L4gltxx+C5GJ_D6?!826XQ@uGw+9M`!gtmg3ATF##(m)E9L=xl}SlyGX*sO zMd}H^dLk-Wd}r&^-NnYT+zq!K_+#D|GpPvsiL03|wd9hjg zbCM{X3J9&mElY%t2+{|M;Rm&BsI$fn`0`l7wC>dXmK0~1b8p$qeg?}(G*fSECq#nC z;=5r_yE(6Jmfr! z_#Jwxqw?FQV(n_${4Osw3|41~!o;0tEHHJMPI@9lxxLx00Ae&L{eiu<4X1 z*U{kg<__SYAdQqp4GG-!~+IQaS|q)87EUk()yA#;!XQzdkiFK zn}*^4p3Yy`^nv#G^&s6Bj2Cao!ZJ4UCO(gzg#w|HUurn7^C4DK244NtX_-yGm}F_J zB>YSCS;Z>Fe-ad!f6=R_habibR0|G8sdSl&yGv<6{llnW2{|u9p_f`?1uQ{v*)ZsM{9a3BHvy-O7jxZW>@G1Jj z6jFO`OZ62K%<|fWV~zPWl-c%8oF(r)8mhDr*eQJzL@T6a87IQi_hwpS<^+b{Kz}SN zcXkg19-hNHKyv6_AF%`Y?pBdXs9+EX^Qu zHBmlX&WaD_2r9e^lvAT&II7Hh-jxGrM?A%^$1^dlBC)%r`#4D{3Lliz-fIy{V^4Rq zQ!73^UOf21eiy|*q3Ft3a&F^Z=aZ1{cYWrs%0etMk^af)zQ(O-3nbiXP67gD2;BY*qvfmK?aImYw7~me(#I9Q$~hl)yIr5( z!CQ6Z`15iDRZ727NdsFZDIJa#=y$5%Ehc~O+O^noui#c;J!DU2?zNX4DZ)y{0 z+7pt}ta|Kw=|s-l_s_Gh4~4Y|k%EY;sT(Epj`5{$XdWc?_m9U2Lf#mUaeeJ8S={yH zxhj%gHFvhNhuU_GF$sEG71fbog$v2u52kG}RQluRf{|(^DX(?uDGJVqLayre$~YBV z&bcA##%>+vMU~cvzU*0ui7h{8)qKpEav`a)RXdc9ZWctPO9*)fb3@TtaIeW9?lrlv zDqf4Ge`cyGgku+n?n1&tX>i7>(aR$SWV83SBvhhri&!@J^8piggq5*w$+9cwO-H!O zhJ+GvdrSC8vKzgtwNI>{HkZqlzSp9|!2P9Qz=yoVH9mzo`BxfWWYMh#eblw-)em2_ z&V}4yK`Gm1Dm%{rq1QN^x>{X`Z0IyJ9tGg38B3RmK0~6Za>nG`ctQe=(^vHFLZtbB z#>K982cE>9H~f5j61Wkh*-<{Gkrv`poLK6ia!+2bc#TxG$Io&-9vqx;4Ub>=(Slfw zkq8tnhl!avaPbFYYSWA#ef-A^pYf-g&7pSE%^F3G2ktt4V)W=rVa^Y*Y9yb?5{}Sl z6SEDUH|x~|sbMQw`Ko;#Pi$+K54%fJ0Qw(y8$a|=5^Ml^UTQw5waEJnmIL=orC>|V zZ(e)wryoN==C(YRH{Y?tU$WlMhyt(xYJQa8 z;&`>R8fH(fghhVu2;ZaPv>>_Ts*Nj?)3A? z^W)s}W5+)V6s4Dzo^?aZ>@D$QIa3(FFBLdlG|*7!{jP;ene_Ji9s#YAt2#1_5wsEC zo0s>B?MSPK%&Pi0o7fK!nzF>@{8xnEy89IsgsgNnxy7A@UT^$NR`TG|0lK3`YyaX* z=Pqwuy1V+{8e0E)*j6bGPN>iwbWlSn8CIhl4I|X^^Y!+WBX+K{IH5`wVQCAZ35oU4r7RrnG>AFSk%(fQlSP$9pTF?_8Is0AN7!J7C z_T?q6qC#=v{oGO)&z`Eea`dQ*pwG#XrfAXp>K@W;7)0sU7-Ao z+&BmrFf%cA8%hv-*ZgvQAbo94c3rRh)vplN7WPN!KXq((_IZB3?K!5XFz~T@a&EWX zSIZ@yyAZ@~+?)`3UVdvkB|?%Ny5>c=GdBE(q{5LFo6RPbs#1R0E1=kq=c z@Qz4_h9leu>o1h2S&vCcuWDM!vT!S9Bz=oBB^2<|5F{A!d5MbR58B#&o%SS9y~p}r zj=m9jhWc#vK!FC{!EzgQFdbwH6onCU3;{qt-jM#ppaME19MA%WzYu}bB|J1;q%0z( zSo%rfz9+`H%E}GB&5-E(#*o{#7y0-J?ie)!T*aTvdj$wn4|z-F`1rVWjml5m?y)Q{ z1|ldEg_bh)$Lr%3S6J?S9JQ#cM8QHSomU^EX@*T$M6xjsZTWQFPSp@zb2I{d*|y%J zko+1*rK2~6BDC=xF6)&+emh#y^>kUhMW6v0MbY`+-i|l==+ic-zfKaB`zrA|!0OEm zXDK$``ccTZVHk1lm1=uX4nVKRNmkGCB1_0e-C9X2; zmc{-Ji}qwED{1}y?=zMV<}PF?rglJ)_;&J#-T$tQHyIzSU6&r=7Yk6s)s50If!ol{ zGGP;o##kkzus7UbHF2-+K4m>JWWyPw)#dl9L!v%rLlrDZ-Y3hwUfcJUNSpZZYlETXSH|QBY|};N~#7$W2C% zUv_7khcI2sM$5#1e7KI`fMng*-$&Gi@;#e|14}c+d}p8sKY;jIyuAG0!M5FGY|#QK z>(r}nNC!85=jEr6`fSLQO4(9q{zcFCj`D_)a`4EOy%3J0>KJLEe`J#+XFmdpZm?iU zR=T;-XpM&8UE(L_?DuhaJv?MM4r9cqD5hr7SXn%2Dm4Fi9b_A0o;{YVN@c&^=R+hF z?1p@jMJ`&+3gmyXz1erYgnp^9%+tw*RM?%8XV9?*!91lju!wuqmSd~jqgP3wnaK{K z-{y@Lo4lxFy-{{)bjOGRo2IUp-ML?2;%2%`U3s;wRkVF-c>b){o?O|>XOgM%E zU)D}#d2I%$`(igL_tuOLQasP!5w32?a0ifHdf|D<&_%!& zp(cx1hTkV9c5Pz8jfPDj9?|wFyKWqNqD^bc7WyH~UB8A<#ci0l=-b2x1=iv~DlAMR zfk|V??WoGRqba_4Z(qp+=>LGDF?lRLcaGDnVi-*?H(Sx5f3{X8FW&1ZH43Z43tDc{ zf7#?mKCf0L096WSv+Y~e_F(16i{?&7Jkv#m&pOIK59OtcS9i^w%h*DW9-(nQ4{B3?8F8KWMb3_l}%Z9B8Zh ztw9LVF$twV{tJqWSa_2oXwOY>wxQhU+DLup;6cwXo$oO5(eX1ykA98(`fv6+88PtS zrxCXw#L(W=4(dj91aO#_rr|S_(SLWp{S%O-ia+VlgVjMl4Cv2y3X2t`sMEvhQ<;r9 za^9o=M*wcbH*F4QkwhF(h*9Hxqeu<&Qk*SoE*OKVYP}TZgl&vj(3$;N}^M2MvUeCXV`^w6{|;~vU1Pcc|dPFXjeomWz zZ~LHj(7I0p#^RzV3R6?_iJYgcMXk8fsVfQrK775>JoXc;DLi7w>>Ymhe+Z%?I6J{C!^k-*)!{Y|Fo@eM$y0wIweh0R9d%hnqR5asOiHS@Kw{+mFm+HP4z~ z02#S4D2~0l_T1I`URxrf#mYl=zf{dK^Zi`2 zk1;QSxyun@R6)PicN_2qobFz~I_^!7MMrhZBT@5dJAkWXut>sSrihyfsK>|4DQ{5kEl z2yJ&bd1R7uV&Cx8{iCk&8+t$=X_b_1Gw?Tx?f0n!*_yTc=Pz!&k8Pp{LF&g4KB;BQ zR#AJXCE!q!WnpkvJ<7^^+f3^p2pG5mB&r872L?1-#L-BKKz4Lxe_qY|9F zS%)@xp-N~2U|V<@=DP?12>DjgBEKk;%ePd#v7m0qQB$rOczmZl1AUuGEzA?d%(5)N;*YZrFsjT+Ck2ePP|9o z4xdlEBPm4L3qJPx;||P`ct!fc;7g8D4>BR}9Rgtgg!Bai41T@t@%E+zXYyrT&l?Hm zs{vJx_GUn!$f3DI2m)0J1(Dh{!rnAo{en5_TUQssywo zu6+0~K4NNXyp71(b%dZ%@^o*lm;ER7(F3**>a$H#LVF3dpC4^e*NWKFSjGWEBKrjXJw6!)63#wu^apSy0=+FQ$m3=1?l z=HY0-vy>ac^8dkzMlqByQ}?CCB0noVF$p&!mzDp5-7Rge6jfc>O?;SdyT~gn_DW`T z*SqYltM`^^b}OWT7#n}F&@{KR9jAD2Qm|CKIAh7}O(W7K;j84#QUBzKsN0-~?v^cv zNnaYv^xWT~D~+rlBW@{rnuhWGp!@6n*`JFBQr~b985Df_Pj!o^z-1#}2TSXz($^V1 zxRV`E-rR7w&$h!)8s#Z4Ki6tH1>G?`7IQW49qdT6DxIn>X$@Ox>t2D|Qeu%wH$mvO zrwV`{(tz;&rqDRw;oZz)+cE@(Kx>LSIcJJ-y<1ACD1lW1jwegd;6h#g{>rpTEHhV} zGH}m6@4qq373=Ho3l%$a;>j6b{x-%sph~_rTQ5%=^F1Ej5Rt|uAC@Mze@f^D&A4{g3$}Mlzktj>mm8IN`kCNaz;4M+WMjfcw~YMF$*{^8b+z*Zr0 zcUtnb0XZy}FEcLDx%LVx_`0M0-cUp+*U5hTUx6Yy=C!|wJB8YiGL_|2^81w+wu1vs za5zZBei6tMsLmhrAp6@Ie%>*+>g6QdGf}dkeZ75&v$2wYAgqRK6xhPI?aresGN-G# zqQv4QH-w0sD&V8_tLToTg95rm^up#2mNnxP{eE2^Iaw8Kra&K~*^pKOt*k%R4MHln zn<$w+O8zO89`8?h#B)^t-tbs{F{k*KnAkbv3$t!p7*^B#z0c3i$`lD)Z8u$s)@Ed5 zKO63V_MA19gpUJMrVFN0($zCHOj(a2UamgdHa-e`!<_!*!(8n==bxENK+7=0f;9;IVsKq0_8RP6vq= zB!|hjV`JsbaYBx4E6F1RowvU&$^1)nF1vko2an-<4>Y#V>e-JaS&%h3rb?gM$1{;H zzOIcAH6LF&y~V?&4Gy%XADX)Y=h}W>iKwFu)ldo|#B92-kh#pUXQlsBaOuv~q9l<` zRw2c$ow7kl&9(AUC}kFX$xX~a zbDo)8h`~^*%_I0Xz-RY=jg3n9MdEHzMhE&=z$c=uWjgpkuEzvun6sjv$>lcHF0S-Tk-0hkWQSvfrdJCt1@wTZ zL6#WfZWm(2VX9HDW?W%LKffCWs)NikUjr-fHMA0^38}QzLY~6OyG;eN^;)k%xK*U8 z_&ub)B}jMm@myAvzPR_pu1V|lm}jVu>&m(33zsvgg~GR_V3z6@uhB}rmhVP#-Ygc> z_GZBCWDVy$n(WMDEu^9)2S{7&ytTRKDm;6yAxL)<^~OJHL$+!QXF8HM0C)xM z{q2G4c)`Cbe+E!^-A=TMdqpn8A^`vK)8ilhckTJ-RRid7r-<%gigKtukk7%-swCn6 zN%+O$$FDJuM&kdBbqW|F|8|d{4MCut+rJKkZ2nxT2JCL?3)LfXY^oK$h!WDrTzS-aztg|d7f#TaBr!xS$&N3aEnfWi-uy zP0uC=8~;wv8m0f^QFzE%fExq{{K&z3g>aRo+9CkcVUA0ffc$pg?H7y#4^3C4e&x^% z5^ns!Ar9e%IF`n_exOMMw;c1aR z+>j+kZIT2(eRD$UJgy3OgB2~EOY()HXNCwd~2`8e_jkZTXX+H3XNd8ry8cK`{qQf4`*6el)?3(u7?C&tb``Hx%3E!z&CU^!0wD ztR}pFbZC9K3FotF-?Ve=U2<)#zWj?>|F^KJ{{e3Fg6eDsuNYYm+0MO5s+q)#{Tr#B zlECe7fcQv@rbNBG?g6`Yyv%R{yX8R;n|~gIYl~vdUz*~#u&EucTAl{LY$hJhCQ99T zT0XTXr`Uq@;WnQrQ>KrZEMruZp2YLy4bXVGQZ$T{a z{%^!&W~{OHeC=IFv)qh;`%j%uNMMicpWgJW6shXsEN@=jxtB;~>=9*5Wwj=%pA6g` z|9Gx_SC_&lPK-sIWJ~EthEpF)7^c3=0SVXS_oO69WZmUE`n-^xVw~ok-lEj%dH3-m z4a<_locIpU_6hQR>&uuTZJ=GYHoubU{BgeMf%{_+19OKho|)k1h7c5MR5y}6jRlV< z1z1V4+>t{I%8oa7VsrvZOs7nq{XN^!IW;)>4xbKm{Ghwbf3}UybXwf!_f!MAyV9k8 z(L-5z|BC*TnhB-}ZgVU#wIIGl8~O`s7Tcs(CJblD?^lj(ac=Jt^i)sGPOMg;EwBLZzNoEQW>-~ zwi+fmP4QVpQpV+;y?@u8LPE1g_RY((&{;?(-JuYM9NkFr$Nz>%r0J%uJgdCvY8ST8p8qkNj*MS#`qJ?EW4@Tt3$s5tIlJSH4OnjUWJDj!*o$uPcEm{F zuer|HZ0b+dw9vvX%VuA>4cE)&H!RtBT}k+4^!|d~l)aO(Po(I8Vd=OK%<~IP0{_+< zRZaT)m96)OB_EQlJ^Z{{6xEwb#kYwvcoJcvwnUHc6%2apR?VD@ICJ^q>k) zNrF$>l7#pf)9EBv-0;bJ3zwY{khy;zoHv}{<=JFONLSKjd_5T= zZJ=1M{Pe^v@Uc8#xSe?G?gDTG7;%Poc)PDxyYkeMzc;km*@Tq&^nYepl05n{5cM#_ zDY|e;C_DX0({^H*?0^_0Q=L$j_)1lO;nu8mHrMI}aUy$~KOu^HRE#l!;Wi z6^rQEaMZU?FtHCH~wS)^dV5$Bsg;_v?9afrNqkJE7I=A)w*D64 zq_S2bLSX&UTXOyF09EvYJ+TcCy|ryTYx9M=763pndG&=e^L4c$neuF3V?e(uIIFx! zbJwCa@|~m$c`t*>WBFW2BM}rbbsURlK|Q=ZLKnfyrlCpd@<=d$c(GP3oZO~oY!TDI zM2pfBcGx9Es3nV9`sQlbT<1YVYX*j-`-6+Xx=GcSdG>R}=U^(Z`7$oGDI(WoPE|-m zTDF+VZ4Ik|Q%ZPG{Y7MQl|Eg21=nB;Rg#)Gi>26NV=X8cLilC7~&t8rF&Q2AG{8+Hd*(YN(v{!@D5z`K$(Rt}?=HN~6w+_L#i%kXj&*iYd$RLJ0 z?)*jMQHQkgQBN*F85@i&m6)Fu(qya-TJ8G~xWe+@c!s~f>13s_MLEiN;S<6#MRPKN zXce$COuBNsr_`1_ws-MkyOYpi4HmwDMMVv#vMsa;a{#?RJTRiu@PHVd?x&pE|=f?^7kQN0O)ZR+@dWO*=~)+X*S=z z?kQ)5yh));$x2lrh=NaxAXiN+{1r(|MGcii3WXoX@rm%+Z}%6I7Ah|RnZR>YgTrTL zK^bGwMs7%}>RjlMOB-yaxas{y_$P#9IGidEyRKKdbPFje{K5*~`v6y8Bk=xS4jgcd zom>1*@R<24{M?{Z@p6#*xytW)kj5nm&t z>(@metDB`qNy1ou2B^ypsS8v!s@=A62ht1hr!j;Oo%6yhc!kf8I(_Yv%*XFgy=^T-JNon-EjbWgcq+%z`5_L;L9n7XE9x^U zEhDRR;ZyV7d|xi%@ueCZ!q&$jI(xAIU!U#v^+_NOZFMjLV2h?8rls!)5;}{pTy`Q?XQiW43X|C+< zgl*W*W!G(ehf>=%pv;tsao_2!9(Glam3|~IB|7gYFYGSQbQJ)wxP|JKNToCk-h{Wv z6P78hfHb$op1nD-IYV*l#DF8b5qXT<1K*@!r}J^$6ZI&h^gJjffG#7INRR^ zou?H1#zI%Ubk%;+Z;MJU^?$p*xUeFF?QzPE34e7#b2n9#q;$o(Ee_i|aUWNK(jBYD z$I(|aTIkbUiiy^av2B9C5K+au>a#P47$f1Ft`YqmmwRVvDQhD}USJW`mc2<7T08ZW ze>%?ZH9zV#mD{chGE>uUM-G?BA4b-ubCu-!L|N{bVF-c!&PFO= zZ)I>XMnVIOzd2FcBb=>zY6X&a=Y&l%(}G}U`L6`nb1Js0)IF|&eSR8L$e@2)jIaIw zc7A1*5_Iv_ndC;dX(NM?);qTgvI!YfM({CA);|&5Nd&uMvf44n`v!g^k9r;QVol)r zELP@|bYkz=L6LW`F$0I&ca6an;C7&_8hD$bPRFk;R`(p1`CDqP5*dlG!tI7(?z8eO zzbZRe$aT@7Q%fn~e6`2>xclOQzfcL;l0%}~MTzj4;oC_Nf=sxMwv!<3c`l{f;_qAv z>*W!0ID#Xp2 z8rHnGnBtWvpfSn56E<&7>iRivzN!{$crXcR1I1^5XH8XXCKD+tmSF}aq^WO3ps9#dL7wtow`#a7hL(T>lEzBc1;KUFwVOV<14Dj;KvTqS;q>UQ?N4^c2L(TKMmyIvGFCH z&{U-Au7V*E5xy+5tq>xbJ&9l=U!lgWIE?&a<2l~jZ<=@iXD_XK0>-ubTA|mnQ!nol zW(MKg-I%Z0#;#@OrRge+!gF@@X9N1zcb)*He zfskd?Rs@X0BRP6)>Q8Fo$;+`H=HC6}q~~A&1Ku7oR+8+_#%-LmfWqntdMnds;@anF zOz+aUK~)GGx7inxKfXx(m1&$ zl32CA%tyMSko41wSK2*g3~Rh*nEZS!t@-`r_F-0`gUXtms<;20*{#Z&bBQ_1U)6)% z*}$3Ik-4S#TS6$Mz~s^KeOc;^X6OG9yD$;4jBhuiyDAI9={0WXfzSxIWdq%cH@^!*zx;wbo)zbEq8H z@~4_2+meg3V;mKR36gm^+rE3F-rMXjLy znN?}tu%z8t-BFQ4S(XOe`$)?U^;u#_?HNNyI2;tqg_&A_7r8g~3>R7)Gb$H^NN61k zX)}*!{MD7K4)%bmD*G*J;J0U;MOBM>>;p{bh?Tblqm%>m!+3dfU945&pc!4liy;UmqpBEuU2RQ!Oaa0DzZ^PYYg?qKJ5z$r%-gO#V2 zC<_m2_yRUFPiQ!94WTGv**J>4+8;>C%6=t9bSZ~n4pNuI1@%u=NP@b~nBoG$&4jb- zcTKu{RRA3mzv98=iNMQHqMDUfMdSQ16WV1|vaGnmrPTbq*8vMM-w#TyJgm?`@Gd4n z^T_h+Z=wu!<}<@+UR0>2-Hq_62P$}Beq#UPa_WC0w372jec;WV3;#kYs9-2Z^Po?P z16obE=%z;(mv^?`!0*3`tAQl!`y~g^+ZY^;acwAL0$cqmRvC%rq1Xig-8D#?pRf%@z@*a5WE9hwuMc63_vBy?uNd z0h!WU!1PQ1O$p%piWqB)Z?3q^{Mwv;o3F;e0&F!9xzsjW{J|bdyogr<6Y~|!h44Do zVrPuQB9Ca95H-8FFS}H*bkc5{rVoEP4o$qbz00r-V!s@Jd==ZK&(a05BmritV9)fCn(|N& zqcI$MrAY#4KS?Qa9UA7^7=k^OjmkUXL?MciZkR6H*E;PqVv0(WMb3pA zv=y7B1+9PwcmYor}+Uh4JmZ~#8R*<3A~ET$yG z_%2gszXXJhX(@c^ZINO(Wg7te{gqoR&uCZuJNz1~#GB$yjb(OGlC2fD)vKM&+~q6~ zoXEmItK}jfIJ}AL4T=-^K+@@1zeH?hQA3h@{!jiigYMV{PtX=lFq9vV!(Ww6m6jNK zr8n(_S?ln>PYYfs)OqffWq3bkb%oZ|P@1V(jr|eE&gIk)nG%*@(RWz+5l)mx0X3NT zC#UoW{)+X~{WB7Q6>c)Unu~Fx6+w4DXT7z>S;m%xx4Dnc#(rSCG2 z9(nmT$zKTNkB6iT@pT^8J024t3&TcYP|CqKcY<*DwnX(jS`sww>A4;Re=N50J5j62 z)cl&g=?;!Q?RnPE2k)$aBZp2oXDw;%A5`RB{Y+Z$BR4FyOlGPv8_T32k_kZ|c~TsB z`VN+i|DHxBVL)0wD@p1oe$e2T4z4CV^ZlxHahiYfKCI|+-q-o(<B4xNzkuOi`cW`?nu zdf08EB^QE7F3Ey>wH_R`gq>vU-(6Wom#3G1M2hXF!c`giA^YG1{IXp|B7L>P1eY2{ zkB+~Vj0x%=0xh=4fu8q5;^6frvs7Qd4{@GRrXm#4uX5F}`+7)E>_Z|^iTO2Sym5L; zp|l515<3-zdV4m|XzAdkVU)Tu4-L}@@2b|cuLAGerVq`+ zb)f-7X*NozeKxRMAJRd(eQ%=8)`cf1N571wmZooc2`GJ_Ckv&|ztA&?P~K9@anNWs zpZsT(zX7F`p@j*_X3fwvXm6iOA$h6XE-~Y|io#XKMj-ZJ@#brzkNUB~%%7p*(VMgp zwfD_$dpJ(R(hWKzKuDjq{k05!M7GqVh6kx?F){Vb0?T#%WOYH=-mP;nNnY9e{zIRq zb&L}Cx6FXh&SPJ|^#ot7KJn;8@xcZBoHDP`iPmcMS$&r}wf+SkTuP`7g_KWi?wDS) z6Z=dRDf^v4DlSR-X1*gbs*>a%(#m~fF5h)q&s|{L_3W#HLqVQ)O~*Au60>)=&5Nll z%IfgeQCLr@bnGZs%YcwP9e{1JTi|o~Wl$_|Z*Rl1pC@E^RtHx|BwXz9yA5E(cZOcT zzC{+S(jy%9&AOVbPmTlTF~{ck;k_L2wjhkpoMa-3Vpc_sl^&FfE{em8xOE*>LEkD7 zNSv86<|W^1FN2A~RFe|XPK`|gEuM%A=`iX;OlqjmAXxamiB$IB0w2V{cA&)G00sIJ z(2_r){u>1>W!F(w1=UszUrkLdT+ZQhU22fZZmWhCU=1;gl;Hk~Yvhl|5Zu-bL;xd7 zosdv9w*RzzC3^G$@!zi8b|{uAKhtPlb0xRTGVA5p>fg zbM)WAH4?Z~Asd+ML4`S+AYG??gbtxtQygR#dsaAZ7*SAF40}-3;^wCW{ce5R0C3#IRvZPR>`Xq-}AX* zt1bN*W~dnSLH*w<}#O%`(FH(U!am&CK*1qry0wc1w8T-$JSRyMfq=S(@05&2oeG^Al)F{Bi-Gd z(w))>C=A`;(A^D^l1ev7H_{#NjsH03JnQ}L2iIbL``-J?2Bq!WAeecKXhY#MOy;_GR~xhm8s`M`31G+oF(Nt*#C<@tDEjM^+KL2 zKk3O$tN1qF8Gp!UCq0TELMi`{@0X|O&*G&s6* z_KRw?HH_C&MWlt$Ma9rw1{&Uwc|_2hyK;IWFpJY`lQ$w!A+p#9D}^|j$8pLmt4eo9 z{@7boX;HZepixkG0Ra=ffr?ZD}C5M$d^8M zA)(ScOk$OB?)Zo!=0GMla~hwgQa_CRtw9`tCa}OId$Qxw$xx5L7ohUHie*Jt<|5#@ zz^jJQeyS?MfbW8kQ|6>bzF4gjpB^(ra!8TXuQD^bs1!zizJYrjGFHzJtX0`pGIyB?Q>61)We+~U{m-OWpeWmk zCwsEB^eTe+(^qhdc+7JzWflI{)Dq3^FwN%FkYXK7>tUx$L0=4FCpn6zH{O!rgHbHs z4!*C5T?BlDAy)B;moEl$wIoiPbO@R%u^K>zgZx>sYjUz0^k9RKWR&CgxVN{}=PQUP?{V0|Pv68_{@|x>fr{Tg zk~PficqI&<@PYreDaM{4>(ZHPGe@sI_J@+gtH*ee_8rrGo%d;7F}~sWVvXE z)4sORnjPyzf!-VvN~I|gYEwRs1p3~6B-tz7mZ@e*UfT!mFQTl)to3zUQKd)AxG9dR zIiu6OoX?EDg6Do&e(}C*sgC#J0>P+8DAHQyg}s7!SFjhh^ZSQQL_Et-gF&Mu=-Ov= zUC5xVOF&&|>Nt|GfQrI?`OwC~(6arSs+!SVa00Y2uzq4ryh4rZ6vxoc=SH#RqHoEb z)^~xfu~9%*Vn?{lk7sgTm;(;!|1j`#u>`j{plN*V(~7vEYN_3iv`F)ciFAd9fK$i+ z1%TUKGxh+P(cwRHVso!`WWnb7ZwV@0!~-!9yt4g2GeX9%xm4#Blo<+>^+^f*kRY0{ zII7p!0@RdrR__s5S$DBO9E(RCRsNX|_dwD{A+##o9?Rs+>0R+#YE1mB{Q~mtVg`Sr z&W30c!tZ6MD73-P7|}Dy{k0tH;czP6qU-%0r&W8yQdHcjTemWNjIJd5H4^rh0#*;bL^;QAJRuPF=&SaSx*CRflTm6=bV@V`rsW=vbU4d!64 zjPRdf9tB+d-yhx~?s9$#ZiyEDo}hM6wV@YujywE-1D>uZ#ZQ;5-%I29_yLY(mFXcZ zc(IlHgZ*;4NofVDqxJ*Qz8j1L%o6jnV)=42CSv{CZpnw;QMB@6@blYOj#d z^@xZk3>U0Chg;5-o`-T2l$@MulAaCGeL)GXoI0%YvNblyp>)>D z)>5zv0&!SFtKZF4jn$Z&tmWj$EpMJ38-(qT4+19>Oya*M6X26E311b=FzcA}9jJ3t zmH9TCkU`k~?Jvvm0Iw8(=F8Mm9B4Ot(e9z^r!ok3Ba6V255JyBrl%rm4^tR7%Ld%( zOZLAmrJX;QQh&+7!dwPdU8j9;9z{Rhgji2zg9(9zkWI_q$R&zA%tZ=Bq+iyRQ3#MpqB_u zwkyO4PMey+LuvJ-8mrGIWZ6*uF9MtC9F@My2JQNz_({I@blMreW!Yr~43>+hx{~Tm zpH)2xwvyW(jgaN~+kdX-HA z2dj9y5$TfOBY=YMNa>|l7Lnb+5+EzSi!GE~mAi;W^Y}42S|XOU15U!K0G zCltW`c*PU5#3qaB@C}|S%zhv5nZ@iiO6%~MlUw^Dis!cARXk#qy zgvw6p%LD3%ps!xZaKn12qN|B@Txn#k$xKOYu@gyeN^2f{_F^2u;X)r>`n z);|F(v2K7?ip|87oh3#osS{Se+T>tHOh1CpA4p8Rkmu5uT;PAAoB$WZ_V=gZ#LVlbe+be%4@V8w_t+DPO4m3LM2;pJfxI?ERvY_xFITDosY^01o0Ka*{$qm^DF ze0N1*$mbOY)#l7AMwFFK#q&J7d{3vz|2EKj*!fD>0v_%c z7y8%8e$D1XvhV>JG-?%BOZRVcb!KenXY{Fd_CpB>d?FET@Rt;7i#Jk|bz=HBnoc?iC1mXyZaAoqYM^k5u z0|01yXmTQeTt$t;qAMK=b09KlE;Jy*sOca?dWjq}b5cKsyiPKq>_P~}$M>_f-1ZdO z4{WX?jnwjIi9Y$m<`5o2^z;8P+$ggBV}>_Z>6Q#X^IE$`lIP+~+)zT`w!I4f1y{yw z%oNNhFTNdmw}240FSScv_Tz-bHrortjove`2>P)%3*-8#!<$yE^N()E;QoipX~$1d zx^>r^e(6&xOFcSF_PAjHwg06~$1lFYqe>S?LL5O^)Qv4G)L)!L*`chOnRBN>V4T$7 z&12@|Y%2D$ztXs0RP{^NAuAi8Yr_)UK|aIV!-|y%s;+)-sf2H$KU0U7U#cjc3fE1> zd6A;5_K_BfYeMy?C9JKp$Wg_JN}7(CpPaari6eZL#UL zFLEW4iJGVy@)l3bjm$q?0)Lnr5NTf9Q`XARv{x)OPpeV=t)FBvZrWT=)cXDtk6l(8 zDf+}?x0d?3?h{IdV?5XgQGNBKKzm#%_ZGwj`*w&E5 za-8`7F--W0C>L2|k!7g5W)(;dLFlfqi@D#|(=_E)yX3cb8_J_AdJ7tgt7Q6JMb5&Y z)>3xLn9mU(_=SN>mBqr72sy3r5H#=u#74aeDij^iK0t+xb$?M4lok4K+SKgld(EAt z)^>gVjiZJSCj<#kr;oz%kHo4I`M`%Dg!&!#^M~lv5IspLLyNI_In+34t0bVFp#h** zV2Memf02vxgQ#^dubfa`K)ru@OZxWb!|(9^cdE9MJ|L!Kl|2(#VUYIPoHY>nUyB=* z_^PAd6(Rn!NNowO{s5!w9f>0Ng&IbD@zVx_rU33OxXb`hO=o1VWr3CU4)U%Ruz;@R z3STvS;e3Du00l0jUN&PfYh?;#>Q&83U4_vstsy}n(j`UBgU5y4@~Y>d1h{A&#X-Mt z0+gy|W#SxzsdB(yyMfGCY}|E};2_a(_%u)($pDfW!gg)=YMHJ2z~vAdLPNj1lG^fA zB25Q2L@AvsP63p0L2#V;v9?T(Q48fT41V*2eQP@%d&Q9-$^c9fY;6%iF}7V#<~KJ9 z?wU1x@VAZQ?(u>;*=1O0jm*n>OGSH}6r32$7I_^&sr;msan6Fc6qQJTM1?`Of$UpP zI`*&pN(AO17|nP;USELTWJ74@c$BJ0cRsX7=qFWaY&hc1&8$(jR*of2Br+KSvuLsgMX?#G_;#?93Swafe%JioQR8InRp_tR-Io7VJ5{`9-2tdsVGtE>DB( zYu+%L{edB>s_ArEXMKL@KHeScB_xcS7Olo@pfNZmNhl;6PO^c@8Fi z-fS)CKVZnBh%$}E7#nRe56Qh<;qyp=FPYyWy;_O6mt^>9p%MR@?+aVb&Q^d^w;H|7 zeAfqVBEg8p`u>Ab+i(IOp-1_ICqM`GH9g*a&Z*^Yy25^gHDX}}5 zjYHB^XO+{GKMv(evL{NvC=jW4T!+B4go^P^JbVJW74WhUme*r0HO0ff1zwF5tUG`sWo_ z^$^I9%peaGb<8bf9fgT>w$cX01U>NU)U(%CoOn zp~8zEdS4B;I?RJ@*ejn&!BP^z!(fr+#O7p|-n%M)^wEAb=ZZ+jRkquBQS7$>DqfL( z|1UOs;EhY~)!+ai}?5||jw)B~1c1ihrOJwrMjnd70HNE*8aN~ciBpBoRfvTJf z;rR>-YTa7%N>p;^aj#_n2!F8v;5!$N+fvBVM!)0v(8+|Bq9PB1O%?&7sGB2ZgA`mC z=U#+Lp_&qX{aHC7Lfq0WNFT1Vd zbL@797LRqxoi!aZOX1`d@9PpCf3!bhxGhKU4T;WPi?Q?aaUus%M@t75#7ecWIg6s|bJ`_ho zo&!xXK)UCkHBEVP=+`W*>hJ}#7HdjuNB)JrsGHNzjlgTKN#8)~)&##kazGqoN?539CgPk(wWY16+ahHBL@9Sqi>_imO1WVq3-N7fyJqXJN5yi-QQOgaP<{T za8B}NK@tSKQVGs!vO&jQu7dr0iUY!{twi}Rp;)7)o5{D^p34YN0PWJvA1)cnYYT$m zm+tEK8L_B9{O|^FwVIA_ z-oEz^akVfzwJ##PpX;o2ibQJ!82gu^PTR!dGn97(oHC44Cb;invcmI*`XASlJZdL0 z-%1SC_&<7&jt`9Qj_=ZOQbNb48ZAP1o#Pb257g}@0pO0^(YyTPP#Z(`tby$-#bB5s zx?MT%*YN&3+(`?2l!1XA3NCNxgLF+Q$JPIM~dRJhQ_2mbl@;fSPxE2>K-GcpVFD`RD2}Y~(eaeQRwJ;oHO8^7ud)l83ihmVU~r{C3f=C^x`& zrga?p{gnGq{wjTb4YX0+1)Kd-+uV-ZQWTc?sD|#OCgI`TP!-Vy3-+(`52qGsZ@A#g zhE`uRL}y0MAz`oVRbputs46zN+x?(t`JUO{QQ4-Q?q!fwp9N8eNfATCTqJ+^B^>JZ zktazQb$DR!kp{UgFSP}<{14W+cw$!PJ7pT*a204M0}W9#Qe?>#73AtX z5jEB(&rFDz_ql&6XYQcj7*F%1*NE~({hCSyI*G{J4#W%nb>+xwqP-lHkj-+zK#=j#gr%#Ex_c_G5M9U-^KrHJ!$<38Lw+V zgQ5dVipN1c>nTe9XpMMw*?DAJe<7{uXPmm8(Ph+7Sne=ka%jU?p;d=C-5#PLB^VuE z==d~9XD1GwFyDf){&sWT^VC}Utu?@#&)&7MW)3eEHHv!B$4s^*CPcSZ>*lh zT`D z_>Ix$T;+(%ap}bvV7tvI z3|NZjur#{6Fs9XKxZat~8@yB)nDVK75GZHXxOH7!d)DfXTPg>Pfzas-OLva>^&G|q zy-#p5-QB4LApOM(y~2<5krepx{zk6e)87)DiWXp0BA8ZA9P&#--Z1=AK-oOKzgGIZ zIuuCAdfGGe3L7#8Q(}~w99{pLr0Mc`-MmPT`Ks51M?b>c=?JQm4T(JWeg>_Xv_^+6 zFek|W<*>9*`+D)09e_Q|`qdyjEwuHQ7b(aua=pWve=vo?>P&b0g3BB>{0;{aXpCRh zLxQ&RtQP?S70O@;tYF4pG z7MT0b8pU>fims39TsHlL4xH)4Ia}$uxVK&L>Q^O&7h7%~bxju?we*3%?p{}2AiIXP zmrB!8lATj9h>5`k6wx;F``}$8eXeo6VHifD^TPlq(^!WzuvHH~1^F1%d@fmL69FU? zG~d%&W^C0B+c8erPoW(A!;0Kz7e(Y;<3JE(vEc`#VIfcpB3=Ir9lY^w(&yY+iNs&A z4P&e(mo`P2n!dBMBLW5hG*4J?|J&ep;*{7e<_4jq0Hw3_(~N2QFH34u)KlD+1m)zG zKR?DV1XIqJDQTA5*v1x;Ke97SfC}{6Rd)qmjh7VP@Jfzq*~)sY>b(xT4vb$)Z)7aW z@twzf)?|cFU0`U0l!hXhjMzHmne=n2;nsFx(MabA&6nKnQgaTqsd#~UL#y=J^_a6q zD=pvFVI1eDFqyG|xzecpM}@<0BZjN((C1AP)!F^i-7L87ppw8WF_T$gY&C;5VP!ub zRQLfCAuNAYs^hkwbiCJfg(E6iO1A<)#AD4+9&qHe6Q#uRh0y-EI;Y(zxUNS@4OQy& zc#}Gdi%$!E<<$ZMUALij>$mFH5__t?86XHn{V648=7e-?IpcYzT4x8}+(H8lTp7V~ z9X4@F(8c&I@Q3#00DbThrfhqBC&x>7HukQot&T5Qc$IIe&oGxQFhWx*y zEE0#{;-^Ep(kUJ$bSM$WZZUBiYY1QX&F+wM&WU2M zLBqV(1FAh=hhsq2a9?hWGv0}P+huV_UDxg&02-Z`^u9B97d=a3k;KZ~53@MO^qQR) zSL;fTLtwQDdpqdYhL}CKYkMM%A3I0ZJQ`k^U)CNqD?g&7mXg4j*cZm=e0pvowO(6H zf+S!OhHaoUwy%~&*IDz{#+{;|px~Ks7f1T@3;IH0GfEol=B9(rc}%N;2Ms>N!wAKG z%%SiBcjLV`(Eno>L zF{z8cG!0N3C14ZcfyBPw9HZv7p_K{|Mg?kn*#km)uq@F$?r`cN3Sm(1p6ohdEFrT* zF4-vld=5cI{qM{X)0(NWXw_9z8{YHHtPlhJRK6J}c$kVw?>MRa8!U{Q0%52l<@npP zzuxPL)&DMhP+m+${R9K5TdJF`K)1H6YCqf-I-c;Sg4E^PIQXJox`+Q-*u() ziiBSPFB`DkHO1Lig*dfV(LyEE=7Ov8)htA;Z^}BC!j$Gv*+Z1+{n#z-WPb;nsM>N#KFGCeYFS~zJ=)iW5Z>QK^@G$~xJ20QY&K#SIAW5+ab24P8I z$pB`x%DC}eeCJIt)92#td$3yO#SAZ9m8DkpG>5H^5^-~6`_SmYW>v^6GaL3Zx|KkZ z=f71ZU)&n}iiUe%cS?Oe1+>1C$-w<>gS5^IH6hT9M3G1Xe((5Q81`BOyxaJ6i0)Tdv?uAXpKu4e*#8H?@2=tPA z=zS~k;Fbzs@di<15C-FC0H^&@Bxktrwm8nA;($iCCl%F-=+)S#TnN=;z^(5T$hoGa zbxrK09M5jq4a8)A`y25ivQn7PtcMhWKe2ro{U;`btr zP;U|V+6Lt+TP?xjskX5Yb^YwSVZ1T9l)cyev${oC%lZ&0cuE(h=S?rf!D8re@CHgQ z$8yB=-qd`w9Cv*11rt+`04zJ$+$0-$)AJLr&!RZ71??|aQcVt?(Z;1-}<%T zlasIM($g7Tib9-*dUo7$3vPLJtQAX;BZJlHB$1uuq$Zmw^2-*J=H;k%jJm;aFZxkEUrR z?Qo^B?cH3s*&rpoe zpDDcZjyx$=e=Lh+;q!6DWqiXNlJjIXJI0%&H1iv5ny~<#=Z){SOq|YBrs+nCHBIGaw@b>Y}#$ zIdr#sic{P4Ur@;>Vu4r>GsjHJ_k9Q+>1}dTj077qiB0-m(iSXRl|iKE15b+Ba(1mh zff4p%)A^@20I*ND)?pph8?jhRbc;41v9pe^FFo2d9pQMu3jIzMpWI38cZn7toKuAA zsyN;Ol=|HGUuzMlx`bSOR_u}i`?sgO9x3G0{|r|oQY3SBt`T;0|9Yxtq3^Vhaa(02 zxzMY%o9>!&+2bypsR|}l4GD$Nq$KWadO1!3D*EJr2tv@*CJ&i zuEAaN7M8V568fzYjxQ}d72Fmd;2|f`lBi0DKSH95XJLty&eiZg?6X|B(yNPNgTv?ya-{_!cN${+ ze(8zjMHjl9Z$ne%ro=FIByS9^k;)OumF~E_u|w4tKn7A5{-uWue#^A*V1$b;z4zU8 zE5qXopTM^FPta>i@qA6eGOBF$RUJJMkeiA}Gt_ps*sojRe27=haeBC;>j2vJ!<|@> zd*Qz4q%a_R2w{X&iPF|O$w!u)aDXhUczyK>Eoi?{IQ{-V*z4|O`KOIJoM~u*3VH6& zs6|vEbhKA`q;Mg;+#JMH-~DowUswFON<*u6~?=Vfz|*# zX z6~H7fP$0 z)w38WN6jLJan!#pjnmJ8ut2q^#4Awgub7DQJ>RD9Wc~C6n)84;jFHaW$QsiFv+f?m zuC;30$bDY1u94}M>yGd%jLWo(|1m>OWBTEp*~^91+y-w60l4$=e5HoSS1=_V5itG~ zM4ZRu%*di)VYGUnq$~*ScT&5-vdF?Rx8HDB!C_%#>0avX+bBdl&bATUGS~+F@J>0!O}f3w+bSF#+_1C!%CN10SRf=FF0^~$-=kc$rUK0l#bx`_ ziR{(CtL~5r?-el6ly>p%5Hfl6mHMA#Xu;0~Y|X>p#3w;-vLKZ>`QWeZrnGBvD9!Ck z%kJp|r=IX5!23`0zU&>B9NM=7gT`r=_#Nqgyj=OjgzbQ}f!<4X(dnIBy>Ffk`IJ>h z1FR@+FBw8j{@N@|vKMy+@!!iyRHMYX!0VyBc_l3aEMEl;7FbmlVpq`di_A4dE^h*%N(qQ`z*`7o55mv z8V|hgtbx_|j9gU_&46Xd=IGv5yp+7VkzCBtxcOu0%=JrTPggN^mjE_h56?%dujATs zmKey6La*D(W~`^Xi`)fNH3&pQUL1aAf=*=Md<`BML7)|*UfPrf+&JaJpmCF7tbc;9 zmT{mmpLyzL@PXWWTh54<61!HO`N1nfS13yat_LT5`wR8S25?z$>dm*0a)um1Rr z3xCI0Qwl*XE&6?ixNGqoO4N`H#=$a-*KIH}Ecqh44u|PFo|run&b7WpoRB!ovll0% zh8QX+SdzLX%IM|lFsmP|e;jw$%ANy|i0S@Pp7_0*#Q;jKoA8s`WYwP)OkqTFHr?G) zo4j|p2<8e@(i-GAn%er)vOGy^3V_3Xuh|lEe^AjgdUZ@6UAI?KrMEi3!tX=tfw^CVM?r&ZHm zc0pZI@o8c3-KG*djVOpvkvv>3txDdeeWQ@c^cB?vG}_ux1YLm5uc~5-6q{g3qLsc~8~+AX`LeKYq(8|)4pr{!V;xafpVx3h*=#gyd4AFVIQHEY2C3>G7i#3CvZqoW zC=AT*ba}|yycE{}*&(asYzKDl6Lhno`24VAZda2kb$=(L9a;8Y3~%cpgd)8?>DotB znRrZHA(1!j#=>&)jp&R6t$7)u*Skq&-X$#)0d()+=ID11b?SPs=jwNjADc=Fh~3tZ zUIvH6b*N?Gjmnk1dLC3D${rH-ow+}5eQQVNYzc4DP|wClPN@#lo&leu-m87ZZVs&dy}_UVd6 zI~mk(b$5xQlfOd1;DLrtd@v(e0p<{$neda4iLe1BR(U>7dC#InOWz4C%rg)V4W^kc z9zlf_eohmEo(pN;m?__^Sgz5?KCwX1Y?ioAxc<#x#@14-!!tBWzp<32W^xoP4jI^T zs<0kE6}V>FmvG4;Xk^yQ^G}S2d` z{1J=|U-6=VHM2#iFXNmo-$sNr{4l*5U8)6JyP9q;^@;zt5}na`RsY3cEp^#@hxm*@ zIG5Myy~A%nyS~Mq-m3~0?xJs;v|bh4^q{uPfy2u1@3;B{O7Hf5yk7c17C&`Xv$g+T z!9Qz1P;-JVEQ~A$x%#1^M>%6P5+_oXgVM5tCQI=Q%-sYjJ0`MAjrn0{&Q?XabVmI8(21N2b|!&MS_ z+b`o2l@0CzW5EFTk=Bo@vHsH`-4l-lX=1o3_!K!V_jKtYyrL-1Mv;}A{64Z@U+s2f zet(-Wag7P&TR-9k1Eo`sJxvdH8XP8{G||N^;u@68*cG{Iiv_#J4~XFyhHidbvZchP zq-;Rwv^?s|{bT*;(OBMvu%T&3Z~33ZB2PVFWAPi$$0_M0c|=p*;2#R?iF z|M}`Ba?RsuS*jr};{spZ+2$E>o3=?=wtcaw@Qr&#a7@ZAP?V6GrZ1vir6h^^`Lbe^ z;@;FEB6mjB)d8fLKO8N)=D>alGJ^k0cJ=)+F>KD}#>zUeTJ`cIG;SGgP?+lmsPm~a zOxaor$k51LynHt~BU@Dk_VjCb71ZhF>_fL?+=h&YOsco@nTtUahdv|erasek*S0c# z%5twDF?6NkIod$|@S*hsXDt73{yN=E`+6nhXAm8C5tyTz2UZNY2_Cgybx4S8cV#=V zITC&-)Pzc`*w`=xTd>kRfBNslYe7Re;?zS0%m7Y`k0C%5y{VpiEYS z56rV07A}!AO1@T?&WP~y{cBoi?Pqv6Cag6DEy-987@#SjXe`E_Hfp+(@RYMSwchLH<9He zS&dZQp*d}QxY$l1d-V$&{Em2!oKJnTDK;Nb{-jidGIbFh@A>&68|+;k6Mynn+_(kT z(Ln9+CQ*TE-6MTKD}I3%eHD@3Cx@+>h@yzGx*NXj{0K1-7^V?&%zHr~SwiqfW_~Rk z;sS^cHOwwq{K$nOI}ena38pyH>l{iEf?4C zI=@f*k2)jHOxdi4-@k#JsQ{xN;gyJTbh7d3ZRw>r7Ky(?G2}k|ZIR2NbBi6<6Mm@avm+&5pej;+sCj%Tk6>CdPAktKNru zu{V>wdvLHb%aUb4hLQmd7R!qQEh+=dQN-2j(K6ju&sPT1o$Hi`q}<0H;T?GV^2e_d zjiB1UR-d#U+kzKIkBL#jYnI%jDA4l4+taObzWkC8|pdk{<0Aqc)xcD z>2-5~4dmM)6jffDO=ktp#YA^=j^&*%vuha@9LdX?O`}g=c$<^O$TBgIW)UzW+G(KQ z^9079W{42rLP6r#gP7i0x98%mIrEl3sj^s~w@m3yeIzqT1akxtW`-{oxV-4SoiNur zp;lFI(xR~Q<~ODNG)aLIr)cvk_*s@+ZUV8HaacG^2skzdi_sfB^0IP{F(eSiG^dC8 zi-7q3+mk63RcYpumlsR3N-YFwZS7!wzqrCD(R!7C}5RqU4jQv;a z3YTo;bJv$)EW_?zy<-g#27mPzQt95>j3-<*W#aoWQ1>&@rBzBxAxk?;!DkFU3Q*d` zrDmORi`}tr8bml1Rj_7BL)upNC(08HIl;LAg*j|Do})*WqGSSC+Be7ngM1u|pzRul zHwC92<&5k#V3XabX@(DD;_@LqHOru)MdT?7^pW3dAcgAm%Go^`U;hX*?Aj~Uxj&IXxn^}w9tp)% zw`42U7ko5qVXGw63o5uf7ITUL+E91-;SjEoW~T=9EXX|`Hm0qU-+&Iu)z9r`Xg#q0 z4X`pTt+T@T!8*v}m|pF6d4J@V^x2@_^2oT|vQF*!B~0Rx1A~CaU4j}Yg7SJl5sirL zPsFP)piEyL9{dx6ag-$+h?mJuVzr>(rSzI}=1c-)8|*mXC3#aM_w}DM9tf@`XNL+A zUPmTBmT4>B?0gdanQ?wJn8z(SK$aiREa!vJF0zJQVSaPRiGmePNmJej1ho|_C>p*; z;OsWEOPEZRovk=WfD7iAI8w{+sc0_RxQ67HUQ-VcSU?OpJrcriT;YaKJ?Yb` zR_<_N_qHRHsDx=h5Sa0VI_Q=naWFHcYKMj+yfIsMdoaIek6&tESRD|R$V{b@_A^w| zk^7^7S=zQ6&iDSlncd9lEUP!8-vgmytion4cJ_Sja^l=JH#d1qDEL1sN1_e=o<7~E#h6wdwwW_+O zef2mQwyGDPL~NtCc#Bu%(=bO@AU#;B5p(qEk^_+FJ}j-<7-Df&5?1D*{`3rj+)|Lp z4auNYib!{B#n)I)Krab>Uv+B4D4!L=aVl35ZDY<#EvWhKF_y3K+15II1*VA1?3hgcwDytRyAcO!;W$4Oq13e9V_)%K+Mwvz^M8T z`DR7aba3`w^=vwPdhtrp;CMJjfq*i7Ef2nR9d!ro#cmy3X}?a`y)uO$9c5Do(WZfc zk)Z8uSCgv`MQd6*?GoH-c{;ifq8h#$H7iwj7XFsO^s}g6F5v@lTWDH}vf5h;dMx~k zIx|W$!Bo%8e^e?&DN$9dono{s^J!%3xpRTA$^t2+=4Po9 zcb?*&EnW|Q*)|EAhfcplQ35`s;koHrKrv{_Hs2Cvfyu-8TWa=8(W{t{$gN)PkXHvk zH@8;;D1ZDo>x7%k_k{&(;s>c(J!+J3(yKpA4b&?wphH-dCXG%4ni5RU*+!BZ?ZrU{ z&Yk78xw3ft+Ni3f+KIv8Sky~~F&&zCRx6*RdOMie;-nM?IW!{gt~*ivXf2#64sXIE zd~lAth`P?a=eCqhq96fOUnI3vlLFPr^DT8$E2>DFV%1E`BuZa9(({D+Maf3=GH%HerRhG$UlFVY%!B?F<0fYV{{av}nY;(~|vQ+dnlzNl(l^M5%WHgl8{y<>lHWVSkA@e2yHlPdih7f;gGDu zw>mU$Lxiow7d6kCQD|3kG;4252=(c<^C!;bPz5^G8y!wae!yyVG)F@0G7p^Id~96phz24b(as`-XzK80UpTgI-fo`v~TTgxmz}g z0+`ID^LJa6xQ-F4T_bn=B=(GXeg<1avn)GrUKbu&IIG+*;A_vG*|o$dDeeB%pu zmDLxy^+F(A6V4nw!Jf3D*cY;AKoCNv3-khNmUd?)1gH%2*c$4lYR{eKKBh4tzPaDM zG8VRA0)s};43#q}N8jwlx}p&gu zMwIR>V~_CT=J|rmlEuRi%9(Y*ttP&jfjEj_Z-wEOZ9cR4`vxrf&0$Cfk1iDgE$a&` z*b;wu;cy!4$gGvN@70b|>UL^lMMIMXE=?<~I!WiRQje?~rsJx(#((epOEE71;Y$tz zy*xRP_pa3nV8JK=Kw{xiDE|vU5&|`|g{5AYnku5kO31l+uTUKiPP9UeaTL7M8yL^S^pS1Y!76#0iLZycpPKKuX ztuq9M2I~u$o!@lpv;j^?_(6_ftOAB@6ad2g`~<~U_BBvw7@5-~+k=(#MDpq09w;+( zK>zz==1f#s&2sgrnKTrY8PY7d@HqDqBD4GPHDYTU1Y%?{u$h9F*4vbJtx*;3HGfkl zt8ZIV`2l~&jvzI#cPY z%n71mIcjiG#+#xOel}F2X0_LQ{FaLVQx%KlOKkJ$C=<4fm{>2fSauU%;VXJtcrDLk z`kSuC#L9@hyRsyf?1AJz>S7h0*g3PjK%HF zi@R2m>ckZVe`nWrrdpF+$~W7~$~_O%?otfg%lq6G(lj8pAwePnijvi%KHopaFusPE zR+j*!O%nIV&U%kQc`Bnqg5F)S`qhP66d62e&u-gRSyguXzG^ z8Ok}CitsP=8pSOO=a${C+P-6UiCKxST4jyqxFg2JG;ycj2_&9fDeYn3+tN~(x?C8T zPkThCxVY|3-)2E9tIWa%1C+CVg2(Bu5@<~Whl&?~FrM+awg)7LV|L}m(-{_#+IC10 zsuV5M)4B`>A{@IrzlHKa#=7hD7Toi)K@ESoVo*sn9{}eZ^`LalH$ZjvT9tu@Y&-nv zEnudMIMn~tWNA_aKQFO7VQu6W1+5feJzX zQ^e%puP1c|@WYW#3vr-xo7jJz%&*l33^cYX0>uGz^DYN@bumzALF}G!*y}E_z45az z^J~hy!TTDzrmvylKK|d@vCk?C;|D18a7mCDK4v8Y5I$|e4Ta1!Vh!rv5tcsSyD7T7DL_4@#>@xaH zrAJHrdH+9_T79e(*20V2^7CHdBPCxqMovBkr{#4AyOzpl7zdx}d#xP63%Gmshv-K6 zt07x-zS64nBIHOfs<~q#PoZD=I#o8jPv>{}kHMUAEW36oDsHE!rSe^N%nEkJ+Buo} zHC;MZzY=9rS^^waQVEIX138zYYvAcbsprN$PF2`-)|%;_IL<#ZtXi{r5NY!t>cz<}#@QeVsRY1J<>rOEiahtv_dFjug`Caf)+Jk{kJ>M|h zen;#oGteI!qwuw1F@rVS*#-yZgdDzoNNqDGdDA=~fTF zF(;#ocLT(YnvMElxM-H25~VyV8tFFzEM-LrJ*1jLVhZ?(Dlk}tCiX|ce8``KWEfLn z6pnAd3%!~Wo8)sbG)3IM*+-|+hC#B`r0-LfH0&(j;fy%yqL56(j?r#^5@!N3h~ACT zY|!-Pyqh?vuWf?HrbwF6Qwvk@;yZDUo~CnN<^p*!wKX<$$TfcxJ>_%*Nh#!L#u!4j>PzW8J z)`VEHl)NemdcAwkaS7E5j?!i1c-LeY^Z(d->!_;U?R)spjWi-5punNKMQP;F-QA6J zhtjEV=#cL2M!G>-QW|Nbn|I?U?)~21`=?{z7#sF}o;BB8bIqxejuRiXq8TcIWL{RA z_Z*v^-SyOSNs1{gtwIr=?&wpOS$xi;0I9;@#dSslp`{r6(+DzeI%^#gW{vA3tYoU3 zrJh%qJhH{sxBAhHC?teVnd#*O|wTOUSR7cZhW{8> za!$f-9y$2V+T5MyuMX$`xY9&|bIGlp7Y=>P`xluG>ry98fYr?&8NE|;$Jc~1$E=F_ z&AMDKnIHo>a4cIt_QhzaUReH-4gx~wf3sx%^{IM(-ed{DG(F?4QP-Mc3<)LCXqMsX zsW3I3$#`EZy_H;rBemQW?cc)4Sxh;i(;*aw=f%-M&01AdidVR5F}I{kl16PjK`1PK z4dK+-_jK@YF%LnG+8^TbO6u^xWl-!%R?Wxg5}NYI;LiN+jK5;=Qm=FGGspW|1Tx^^M!vnY@-*Z#|9%>jep;$e>D=5qiS$LP{A&QigVJN+UT#6h+=VpiA+ByHOG!-qK zId7}mO7Zs*D9~6Xe-{Ea$hn7jq;3YMe}`$-rgRlc=TEi5ghA^(E43lT^2Lx&$nY?x zyxX@G1MxL|Nz8{Z#gEa{49wl|EHLmwO&BF>Zsdb*TJ!N?FwhCnVuM`vpPS`hD(z;B zQR%g>t_+js>XusG*5?^pWUs+gZ#^6uwMD%H+NyuP`op(<9pS6E3un7h*x22t;Aeyq z7btuX>zoBH@7i&f9j5UmO|pO15ym*yF=I@h;k7aW{S2+~+oc80ik&@0bKfofj&v2j z2*mlAdqKcEWxuVAtlVGjmhP+d&EUQII`4pD;^b2Pw0fJj*M*UIXN|zGTmE5v z7;jYe%JD$JG`xIBtmDW~!B9fu5#)p9cUj5O$RCz;U)fW%su|ZJT&TvmykMx+B!y;K zD#sVMzGLkOk@B7(n2Y<5eD_k0(QZc;ST%@3{KOQ;Q34aI_xNqybc z5B@Qcper*QP#}noDfl@SaZpUrRRMu7g#fa??3$wDKK^Ad!f88J<>$|Af`_6N;O~Uv zK%fos^<|?f_rkITn)7lp&Z%4;U%1pvnwxXX=n3M#z0g0Yz$k1$YTR5kECg_)J~Pvy zZJv_OUUDf9t-7;LXE?epV=L5c1?P&2DA@y1r5S)(ZTes1^!F;|&oA579oinmNuCcW z$wLrSvYrPbQ5YrI3BeY99H&@QtE9)#Xb~x zzvtwpSfL^KDhep;p)pg$x;+jF5=Qy-b&N}r%fs{qOwtLzh_u=Ps3z56N1OnVtbC!_ z&-3AO%@y2%rycGGbo*V0P`un!($;AS?A(14TJB6J6Wu~j5!>Zkrip*$EkKoMGGn;R zA*~IR6{BU&8UW{N_G(N>3fMvLO|7_v9LpRuZZmK{dX&HhvW3DBJLG2QU(g7eq;;G| zzOS*xdqpYI{lNGB9ERTNzD})fe_apK^Y)I%PqDX9i~Epqt-P;b*m}WM7kEO3+&T~l zmmu|49-`+SOqq`SO43!euk3 z$=@~u?FCD6o0s9co!uIjcQ#SAU09ID*Y!PNcXPTA`tR%GWbq+xnks-~#w8ulv}?;o zRzkHJm&e!c*=>snSu1fEhv8YKZeqUyE+b(Th_nWW@RJ`kX~Jw))$O=tUi8-9v&a)U zT^9KICGJu8ruNGp^VWTIgM&#Ek?)S4dyD*>TWt4sXfktO4>>(2 zXAhsRO>)F;Z640*y1fbbTei*u224f1(%cL=mmT`@Gy%OSR0q@33wKxeM+Bc642*q z#jeU{YyVQ4zHUvyho~I%ue|i(JGA}9(+oO9kqxa_wq~xe0?+z~qG)|DOLWyv~cyi$|vZB5aWfBaki~ z#E{6?@Ah8k!9cosM|)2x;TshmxOtB}DI@}CgVr(@He+pY#L$G!r)XqedO?iSDuV>4 zHHCa>7AAu&Oi^=wzwW~|FrAC#3HYF?0NDv^zhp6tY1oSxV{7S&$4mq1M)WHE|VpScB3nPN{k&zoh%&U z0r6&-qE91KfalNh1O9vpH;g{*1x)Cp-;~dB`sOp+14wOCr<|aCJhazksIJ`tU#u%7 zVt9`olVgfLLOWM`e1enOZ4^<4MOn}l6>EGH(W2sFp1qnVLUi2=uT>j|i=ls&C`!hxv}=!h7EvUNIP;?5my#%~I5 zYYEAKd8cVV(9e;aa7S+f9MiKgT%U3f)$})gaf33B9fQ}(5~qkaL^RHla3KoktLH%j z4fNXr_3NC8#k|rg_cvSR^{%gU2S}ZVfk;ULBy!zwWmrgP44X=^A?v4KUX<;2ASakO zihqzv={t^Gxs#L(K-Uc1pr83S4-^Iks`3Dvb6}0xIp5xd5)xW}2Z`*QH7uc%f8vjT z;aJ?w(~G?t{0=?OnEsM`3B24Bt+^TpgNfuVin0uLxCaW!>E<>#@XU`#rcw_0U@2uu z7)301iQq0g%YGesk|4T{wAtFu7mwfcl;s{gJTK|L=#?hE7qa~Eqv8WE_Z4RZ{}O@5 zY?UpUa`w!rgx2<^=D>y(RiBsd%BP01olMe#h^(h|>xG89r_Oi3gXetkmyp%?nqxxV z@iEtKoS5_E4&I-@f!v`qVH9_+qB$)kCOG9cvX)zTm3eVw+vkm;+lDNlI&kM<}6 z6O1O5YYAOFEY(fK6s6`3B~*f>eu>(P5%`<2{^Im_ySd5;KVBf2pO%)*rV0I8EGKlF z2yGz*u4a;E0KWh^Rhq%cfA3Zj;T+}t?I6X~>hZSib#rzwDJHGmAe~X1&apRovR&1o zbf#`wy$x_nOF0@ItQ%yFyrgk>Z`$P(Iv{=fX6zVPX~mF` zq0Zqz4TlQSnYR<{`kq=Y`X1)+blX&^N1ws}_Of=nPng7GWhsu39QS0H*K znyO8M+6KKmYShG5>++p9ajmno`NnP!bN=^UhMQCk0vxm>`4)Ft(%(%P)VwA<{Cq1v zs3XJk{n^ovvuXKMHNO~3KaN5cGg()e$YXD1olYi-9jDkE6(*J0Y^(QOe70hEqQm-F zf{+Cgh3=+(iD4O}u7(AegRDL8Z-WHIJR)ScC>Ip0Bk~WzCO>3lRH{2M95oPXLBOGz zcz>Azee($w%J!e8)h9#kaN~C<+Oy*B^Y8Q+M&*J}a6ZxrSmJ#YE;lwIWhi9sNs~Y~ zW>yd&9uk=fSA=jF!zR`9+3WxoYi3VZ>?*I~G;IX1DRn3c*ct%qK!`r2q&8WU2$BP=dwN%3LTQKG4#DhQsT7*KWTpL}5uJS!nL9Y)P`QuDhU0tF!4;eBCL z6tg#adRz(Ru$a9Yf61~95L0m2B9 z&A+*y2TkrgSd(Kjk!;<8$<=mz964`sIRG2~3*aBag_RHsTqb8DD&No?{L&40T0cJg z*d;La?Z`yIoipej`@nS3XDxZnkZ3uvz;(q6NllbOHAxx&@WjKlxz#jfZJ4uCKr;yD zIU-hN7@T0!A$7l+M=!xZEcK!4J@|HyBufpr;Thbx%YiE}9LGsS910bp7OJdqGHGS7IH^*-&|cHwMV9Hl)*MQ01 z@yK(Ts>3l>Xf3*}^OC1A z;w7&jK<=BeuEj(Pkd{uQ3{b21UQ$o9^;Zx8UbP7PMan2Ho~cOmMd|`$>$D+0#M~UA zQ(8!7Dc)sBr$G#7RdNAgF4Vjqej-wl>DT{$-RJC4yE?TcQkm7wA3n|BQ;sv!n2o;S zYM|!2(uitWPNH36QZjHCFewC4q2A?bQpAF%npl|zN!$a=ns-C z6kw+gV3e?4U8z*)j#QNjTW#_wrse5a32z2CawTfR#3?}8e!Osey5MLkiPmefpjk;? zY>=INU5zPLYKhMxHl36Z3-B>w7P)&$lC8Z;!&w#dYN*UJwQF7r_{K=pcDDWim_HH8 zPn>9NN?TB$gZIROJS6It972@Sykh^Xwxr}#Vyft4o@Iln@+4o;5bJu`UMOI=H-7a3g!z-3{yw2x{g|&1Guwo53KMteV ze`R_l6pE*C7gf+WSw##Ee{?;4at_=9ji+os%mPh;$8X~Of7IasCsW|I6DXq>*l;~% z_7NWEpbBpdt*Pr3>fr?#r<~4}jlH^TK+i zdBR+TW`=uW|ETMYI$*N1ZF&K+=8}kUgVwm3Q=F&HZBWK2wYMW zGVy6CW^=Dd-ZxK;r`!#JzR95E;RS&!Cq^@S=<4CeMLa*0S}DD3MJ|7%U3KDYBfTgk z3+w{)Mx_^M%P=c+z?*SkDtnpxeY2+?=|yOL+lU`K<3GjVG%>U6+p15|gbeL%f~QIY z2deM(dsZ3^> zuYSI#kf;xc>E86Q>TnHdw>_=uVqq^VRYmSRaogTwGt5Wtj!kT*PFx7 zH$f2SY9c#b0?zc=^-z=-CIIpwuab$iusWh)%g~X<5fXItf;emZDWb-;U+4!avb4ktUkVKGb zEz@TNWWEHPe#RiynKtD{p&}95`jF*G6nP>sT1JHS(ii|6^M!I7rOsvnwP9w9e~}jM zJo%F%9V*H30Aj8-iKMn#!+qT8KybB;9?@ZYV>;60g5dwCO=zoJ83<2Zb4i!NS^l2G zwd_}nyvRBeNhQlReEB$+Q@Y9>y{iC$&9V5}p9Ufzl{nPHvdj8erm7*OsJr;*i5VD!|;&K zj^3JVp|r~L)i|w}>y7ZNdYFF>264&X+Y!$oKmW81Qwyhk=a&~VJ9cAbfd0bdTh{WE zHKs1KijAlERC0CVRVPQLb(KRQlS!@Or4{oVvVU}1Pifq;la!Xf#7PfN1Qj#O(g_qFn`vE0W4VzSV{-$)gKPq@C5gxF9oJ*`QSstB#a4!Q8O=RZ5$yH$wHrNDF^j@!Ia1L!VY=%C zxN^H3|JsT4D3;L!%v^L|-?$cJvfLVc^=ukF^qBK48rL*w@|vhd2&z*Dq6F(T6f<6- z)}pGid|_b?OcQ`C49TyJR)WDokRlK*Hg4BT{EVWig_roPoUuEoxjDGE#nul}TlJ?? z&Tq6fehU8i>ZhePe)=ii6si&YW2KLWM)GN^8l0PW+QJchyTuIm3$U_j0&_Mwn?AuI zRoB4{uDi6#yQioh%gApBM%NLO=JO~iZ8!wDku}^CDVfkqfITyJ+?Jpg*>PUBdj~_; zs{_Z=i73gb%pI^#9nu3Z3> zFe=Og|DsCT7EU{MZDT?XhR9T8lVOrfSm}Qb~0=R3L9D+QRR&gSd)D5ME=nfZeR6ckS z!Bbdk7*4@nG`wvCaQXih(?xe%ZuQ2E* z*4mhOJ?<03C7-OJVnrc5o>mo}68(|#ksWCWfImf3q<}{F(**61sm4<)5IeQg^3YDr zVIs{503*AG9V@?}rXj6NX!YXUog*i+owOrnG)0TAxP-D!;=PIx-XS-|S9uUJRGDZW z^8}JeL*+=^ux4@|x>EYyA%UqmJb_ddg}c~E`K;Ue^EKn+r2E!e`e}<<%tcsvB4FU{ z^b9h>#6M5oJv17IL%=@Wi1{`3JnC^_(G*DV=BEX%EiJH*7B6l^CbN%R(UbubXOImEQ) zT+YJ5Ch}*Q;^o?b7gK791w>!lNHr%*7t)w=pkn3srJ1dD;q&;ugWhF0S#LF$)%a_q zj|&BfP<6`7f8vRGU$CUuQ+h2Wt}r(v;bMQv$oU*gry~oa(yBA2->|L(^fX2SY; zwboB6&3s=({FGuB#qqdVmd+P!t3a686U0`oHTQ@vpMbLF1P38non4jX?Ht@#kXIR; zmuWWqyu0OzxtSPbk1Cb5%Wq2sY-fBwXPLqT>vUl!CV6xdSFB@}LDN)1z_^K1&$$kF z-GN|Tg*7){?}Cu+wJ{J{ujnH`97NyL|3O{mr^%*$=EzrEx(vK|nywkF4>NK|OaAMu zbnJb$fAt)guP&AweUWn)DL=5C|Fh1kpeK;V?g6RdpDkvz>jP%Hn_5L`t87?^R;18(uEwhvkgSj=UaJ12ahwl6rF^Z@53{*k;7cL5e1&5s4xZUqtF=qqOp`q4I zhUQ9_U(5#Hql#BUEps%?8~yDpL^SO1s$Tn<@f%EVG28n?r2c?=vEqbM?QnLx#AY%ql?0uul^IK=GPCwtVt zr(>zNiWQ!-I!4zaidE^c<5JGl=UxBXV?P-xPYBqi<^Uq6$FT2s=Lx3G8)jv)7)>+1 z=xO`iN3$wlXGrj`_y`QEErRnB*h|I@J#lw2}ylnGzmk&Ra)L}5MB*t{z6)6SY zmW$Jt3ukK#!o@+-%s$>3{E=f=JLR`<|7ke_TwDjiSOuADiq$FSI9`CQx&__h989-` zIi%yui6L}CER>>%`)L=xwn>S)e)T9~6IhFdQ*PcVHe^t9Xp$~WxlW(B4iKU$80h4&RqPciOl<-Zl=)IKB^m{7wZh&ff_ZQXl zWaE`2Q1q6p>G)2d4wf_Ic0oibEDHJ%vwtkPNl>l{WsCN>UjC2D59hA|84~|6X!7k1 zkPkpxd7L6)j>J}H-z9c&h)?10h4HX>nGaca@Q83au%0jaickUaetx_d*fD|KekE#0 z4_8VTaOw#b5sRxNCqY{2OQ9o0JNP1IsVYDAoc#IcE;>9xg++1~u~QwK>VctAP~0_U zsNo4KR8imc-Lj{YD+CELM_*1uMHb1?Kjb46mHA)D2^eQ+vtz1_=C7gV6mYp`lba9%H-pKuIFvTvv4pfb*~A2x3*?ko2Ev@^5doMu}?_N$hf^2AdO@jtVG z^iJ!zdsZT51^xOZ_9Ghd`8Rtw4sn!1C@B-h`*rz<4!MbvAoW^A+YWSaz=c*rXI};H zuuh{eo&*>>BtmNRVcDZEsO}A>*qHLoNW_)ZhYLXyAE6^5T6aWzu!$xDuohl3IBZ_V zE@b|24Y1em_8pvv7;kR^wYoJoM@^1FaSJin<#7X?&=_b zqG0#6Y!?r38V}>AV`>|wNET^-|Mc+>u4$&M)WNfY*y5cSa6(j*+>mz@kRv;ZKl44)EzKEz;7kYZ#W< zttwqwy=yOvXb$|$7ES$Kcjz6|ELtzB2POKRsB0C8{!kas4?0W4iI^*I>XtipH@m?` zAl}jyae*vbeYKI}5U8goLOfRrQ~|W*5g=JA21q7$qr;e{zP<4RPARj`r+*p==$jlt zSLjB=(jJ=>BP2cLr2Ou`=s!R^qgK zToT3*FDdyj<_A$~MYg7p4Pn&&`LZ+z-@6c5)M+!^Me~$SkEnUM9lwB$^Jx_!Ey9z6W@YS&O z!K7y8+ot70y$)n_!|p4X$Zf(|wF~iIzTt^%TqRkd;LRKri<(Z?wE|MeoWPqm6v5>m zCd$jqRb`wmd2Km)`o~$&@j+8NH>wn{rkp|A!zjwicpLGj{lc@S?XX5+TL}2Gh(O{_ z-Aq^+w{RJhh z20ERsV8TVT#)~&Wjwj1wRDTFz{*N!IH=qdZIBN?fyO7Q{R-O-DKX)eo}Bu(T9(o z#S$CW8Z&0$S-ZH~c$qB0ip*DsKnck3<#gw`FO*wHzy4nx$G_IJgKr#NiKsMXlrrF>!VeX;apjgi!F2Jr6+6}m&Ty!mb3X^zNEHM!n2Zqy(Wy-xJ_}FX>f9xsTgYA5 zBd~*5v7cl4DRYD^AQk4|V)sOT1zw_v0->p{M{h2&_-Mo5G(vQckDxZd!Rdx z#O73Qq(ANYZ8omuUmifAv)pKMR{HNziOSZ@MN1|AgO;t#+$v>f(G5@Hsy3h8$Ba)YMcfJopf;?)4Sd^knJP z3$3AKz_@dtkO?F_Dewz>fE zqeC3u((9M3;y+%!R6u3N4oSkmX62^|Eh>?~@@z+^O!%g;sAg!&2~X)quF9?61B36J z{#>T+tFzsWWe)Yift2XW$yOx;OCWPId4G|CYAFglPBkaRQq;nONoAri}y3SX*?p8&HJ?{7EQHDXahrD%$Rsyg#=n zEi=wN{}e2YkK`E$V$sjbzf<uat||Rl(0a&x<&1fP zzNw((n!#E!vtC_Dxnn+bLI*bPKf}s5NY)x@oOh~)(QVIj&y>m;cJ1@gr>wAY13pc1 zw{ryod%adXYsGaDoF}8{cUvB0@p1nD4;Nik^(QI0*t5M*{O?RXlTE-E$^Js z<*oiD?49=e)lMZ6IVyYv+UFqbrw!Js89O+%bB6|V+}abXGgI)U9T3F(D1VPQnX1+L z#yv}>TIwCdBEwX$`nL<2qusoLp4Rq)JyL+DDeC8f7)tBzh~n0T;zpg+OPRHd$S}kL zVbP!|q?l5!U{X>|u7xR+Rv=227##`a{&CK87C}Q1YJ)d??sMte>d9yFcpMNGmfx?v zG$37G6ecg&1@|oM!hdk!p?Y|aFqsmk*Y^zyqjSHgU8rp)l*;1@ttfdjnW)qb}y0rdc9lA*5 zq(y)v4J}d))_3lbe~vd+4W3^;F*|Bm7N&JXJ;;QjVdhc~S!nPdY_E||lgvJT{0`lX z?8oXVHYcNa4rd!YgVsS#8KmUbIf#^^8G0lx@g4~g8^-^<0d5J`^(fUj6ziL(J>v_j zpNCcZ1-pc{H+(XdpRQ7%rSwvwq4^PjP_T7F ze#7GFV!VDprEpok$G*Eq9B(=PT3QEx)Lj~a_KYfiH z_w!L$X{MSQhs!&6vK0&yx@nJxDTV_uA=c&CT2K?5 zK>VNpzmk7@#ZN-o$PQbIaQykxxAG8p_F{XDhM(EwQlbI9jcydp%!wdBhD=uT?}-Vu zy({k?TS{w;c(Mm@pXh?lBEt?YUBy#u}D4h(dT6Cj&;51>VPSRGhBRxP!@F!d*fAj3Xq(d~Vb> z%%kSTz0g#Q__P`oi77!o+V z_2dl#8~Iy&@7&K+RH$vC2b+YN(!8fQ-Q8mn_<4}1nMCTwqF=yCW#IQVUQGo(i-8hB60le=BvHL=N#pa zx2J3u_Yd2?kKg(0C#u5O{k}VfOKTOv!cA9yG|!7127Qu?@}nZHvK56+??$!G2(f57y=cJsxr0n4)sqFT2hxWxIGa}q)_VH1p>&x%!%DCjjSA8 zpCeNi)W2kTkMo&|OVWCPFSDDqI>jqKXV0cJikzLi0JC48OE$-r-CF|{xA5jgXbDLm zGVzmDF1_*L7?r$bzBc9%1AcPPO&_V?7{_`Vzv%ZJ2@AVDh;R%p(Gloa(hNzgJ$ks0 z13D38YYn;hcOtzw_qaf8O6NU_7)PVq__XTn75F|5yeWQoDonR5}>|2hi!-1}7dZ9%EHYZ~?oc*-g+KHmB6CZ~2qr&2A*>$y63K|xPeI#>Cy zVL^YzsPoctQQ8+tX<{)5Qci&H$RnDJ##l1A^jg?ovFU3Ats1IHreO8pIXvx8FQAy2 zqct;ULt&Q0Y1xMK%)^4VWff+LUOfgIf?GWOdeh8NsTY4f_aY$x@57<+ub4%c4vf-) zpmGvBsGi4lh_D%~A;(BqrQV;skxoNO3;p05Q4u^i{1x$LhLk-$9SB}byuuR9Xt;2h z%73NtVu<%LhU-Pp=SD9)dx)5PqA;qUVhjCt zj{Mc}CoB++EQHhS;g*{wsb_T}RLxJnqZ3nq5Cfp0<1s0`r}{lmK>_-7>_Oxj`3kn1 zcztmKZ9#ovabTR(*vUI7%N=2b*%8?{>-y9qv;Aw2rXi-L^~b!{UY&yj44Va zb`z)&g%3+P4$-P)#~!B38)&rob&nPbgS?uXo;H)SB%IQ6{!G{9lm-`Fp^GtvgKxCH z5?ZYuwQ}b2LB_~ibjxSydvbV80}h!iU#|~Jad4*#{*;Om6TWzpEMZHJ2HP4T#Bzo7 zdF8(D;vlkO2O+)f1=560M)~}iGfZxGv>r#ogznD*#C!SU!V8v9n(KC51Hq+cSfFnU zF+yzS!g9TCO&>%)oypvtmyZ4rXE{uDKqI(A?m+*-@b25$w{dXPv9x;S@A|$R{Ts>g zr43JTZr9;OYN>NGsl|`jdz%-z5iF1LYjh)KK0o}cLlhCKJj%_cMI8xq_iG{<`CeOH zSG(%kWkPuaFXRUiqCbtoPJbW8@~))d>N_6;g5LF>vGJp>p7gfdg$nLi|6Y{bbTJN$ z%*fg@oTGwHz{sx*qk)|21+U&4Yu`YxJUXz|-2dmc;4XYa&p(lR` zjzfxMD{t?DZAp{h4jPL<2Gt$wdL$t7$<)~#Q$tX0Amtwp$m00HVx}2_w0)WzYFSV? zwrAORtM|+tCIVJjESf6dP2}GPx}mbj7N_Rtn^J2t>^2zfLtqoZdWEpz6T;-I)kY;{ z()F!ne{>FV@{DHk&2zSg<$&&v6d_SRi|~+Ye#k>oM_l2EYkV9^z==UsZVM_l!SzqZ z3?biqIP$iYNaVMjx-E8+GZf_n2Sz&@CW$iNW2?V^Ci4e{--*j&<4c*eH>*9{JS*%w z5}SAW;H5+#=J}1s>}+gN%gX=romkoDZ!C@G9PKX2tYst=ZH|o{T^VE6Ls>UsbE?+_ zg?f($oLAA52k1XBZh#Po*YVAtx~qc{KIOawIEorNG{Sf#u0hT~#XETgA?S^VKUc(; zuR{y155ho6N}9D~{NM76V^TOY=`c-ANZW+Aa?csHd>C9YgbKP-nN3$gm->(`%@xO? z5O!uhMO8$J^@ia5?t04)})ujs^RsNa(d7i$01p z!G&<@tUhR8zxHit6f!L3jboi{g8Nft?YxSn$s~(vUS620wU+(RB1sPx>v4{K13?KA zKUbtT@KaoK3s^fnE?*3WZLp6CXC}Bi`=L@5%|uDPD&tjuClDOMW0Hm8s&y==r5o>2TN88&kr89Do?&S8}e_ z-cbEb7x4?$j_)JXQ|=?v$KJqc&WvZtXaF>(ms9gB%{%5C&E&M{9Nc@?tn#4FhiXDX zXWv3*nMrcnyv|0VTIsi1Q_fT2X_RmFmQo*4?C!fEdQ-m#F(!r{NpN*}fg=eAorlAo zTD{MuJS2GOfLCkJg`e$*^hJG1l1vK3HTKB#uQMxt*mYjQsU8z&!Hk}5bn_OHgf+3NiEYS- zFC?5Kp0!7O;Afk#R_F@S#6B3OTX#{nWB5HE!>sM6qu>rt>AKnKNCwiVCptK1>-7@? zLX^f*O3s&uR#XhQoEITjcg>xYXWoj$-9K}r2fq=|uwr;-tRZIbCRWRQvSrZT-aB({U?9F!0>#x>hBm3>H1L%BO23*jHjDh@u`Q;(H@z2^H5vO}W-; z3jb!p=e~yFsUJYF$KUw6!7lRoy9h-W?R z;G2X7hiopwAktA;^dz z-H?m>x|w+Fi`<^BD>Fo8g{W)}Bj;@k=KVM68ULK?z(#>|FyrJ`5pD`wj&w4&)5QKo)!jvu-7<22HUze4`_oIkhMEB$B4;2GHRu zPG4<$@HnINhBU>G&_;1vAmkP_9BwA8ZQ+&z5(&yp9-#8#;@nOZ`;Rt<2aT+xEFO+0 z-rG~w8yB&S&20B*UNwD(Ud@ZSTw$rATd!Zg04BYO_TZH=vE`a8n0XjBItazRg5vi` z!3J*rM5&F;gmCqa1R*!AD!caU*Vj(j*@;?^vMNzu1}|g^uj#zUQ6;Ye_}RL)&0O(bU;iAg8VT5jSxD>@!>{-Tbr`gB?xqx%4f9{SV80~ zfQs0a(uw#CkuJ3d>p|FilGw6@r7o;QBgZyrh)D2*WWNZJo(H_>sW8h{bmc|lvCrf} z9z|s5C^iF+lE`&-&Y$wj;rPzZBu&zTVcW=ot19NsGdoaW(OYun9NHjO!b8mE&VQ$g zuFtBIJ7UsHs!nogRkb-!X&*QdE!;u!efTqM!J-f?8yo_JcZRYZC)dfC>lwM~W;))C z_Y)!>9Xw32lUWVV(R|NKA+?8p!vfhEpV?@MP(*Yh&h2M-x{TBL#Z=hxYIIk4uNM>| zVBme%LtGt#L?q#azx4jnkO@nb@@}NU+f&wQMFEvGoAop#;=8?Sd92hQSa?5*`ohY+ z2}yt#4PyrzxuWlAL4MF8e?QOzge=g!D~FNrUX%!6=B{*d;Pn}vpOvqZ#tN9Qo=A6L zlLy%7Tew#fozY<+d^%9lc>xn=b^lcSW8L7_8EAkjX2wE=fQcbr+a)|2 zyN`Y|vYTELp;hOinzrFQ-_&^Yu2JNxFs&5FG(*v70^^h>xgdw&^LS=jr&ejyt@hwJ z>@&2CYa-)HV&NYjG%Qmuhgus=>BUX1`Jaj>9pYlm?gi1VCRaYsa?YQgGr4z) z#@HBJDdpWhOtrGcLRN`P=^IEV`0BX<1N=j@EFe0aw*N-9Iyarlwwc%C`?mjm#GJR& zxK5lc7;~?3Q|_?;2iwNVKCww6XFWkbNM_#=B~KL5AL>UW!YsKk`~LLmNqnABsFQU~ zJ_%mZ-Ug4pwKXdvu!=$4k9Na;4FkQc^D=xX|JC{)-u*ZbRQ`@&2Lm*tD9FA{xmSAx zCmuLY?qgW6L?5Hs70h=7pj!pru0UAjoFpZ3H>Mv-K0oXl)3+|H0=wYvVHv4|h28rz ztoaQ#EU*|sd&THs$nzghWv;x9!UJqF9FTJR(ec2Wfb$NJxjA%qwiMNQ3oKrF%$x}| zr?gFV8w|KnY>JYi#;ea8evVe~;k_~-e=}NRQpx~yoIqIT1W9a8*`8n+riBPP7^xezH!$en;X)7@K_7+4r3B;qODPZvwx>Busyfj| z3`U$|3R;wfEOCe_Zo{%LpU0}u30#U@7}o_jBh2GV5T7OZ#^`jB}Mi27KFFIP#lG@1AS2!D>%z{|NsCcOoP7 z7a;PgRg7byPoI42nmQRj!o(p{2tkKK^hreE-+d90i?>!~S}Rfiz2NXg(qU8TGlR06 zf~$`;6{QEU(JleD;0 z8o!65^m$_cmju3d&bY`xM#x>wL6)^Z-J~h41AAgH7 z+MT^3%>S>h_h1}3>stnQot|nW%*zH^s#qF<*INhf;#nU(YK4Slih4$9p+pd!ru%D_ z+f`B90cDf)doQ5*eU(WY57zdHaZl|h-Wp#M6#cYv;SpH8wdBq>M}>$%Rn;te5-zvZ z4pQY7yFJ*?l`KD@_mDDqlW7Ejaw%7n!YTu33Syb&`uFzo7m z*9`>>@u$W=R^+38>u zF0g+zVN=8b!+#@+NsaL~#QdS<8+lu)x0c6(TbIa2_nYjFYT?pMN(Yk@WKi7Xz{Koo ziBy*pa0@u)-JdncyW8Ee(Rj;RGLn*JVAO4MCL<(eW=g5|XoevXV+y=CQVw=1}lUeKM*FfotOE64WtsM z2X?=tSOQ(-M1@M3(ASvSLDSC`LkLwsxdvuD19`~I&aKQ=Rv%{C=AGo10HL24#)ZZh zBDKAERr50hjJAm8A?&sIvZ!`g8CN{b(r#6ANbvhB#$cE?h_1Pb5R4?1}j8JyPDfw?|gwHt8&}9dv9nRMI zRY>8lUmENiY>;UX4&a-G!sg2Vp1j{RlEGTc=o)2k!RmKzbkGPo)rXT^g3I-A91SKZ z(B6vzX!iJSlBE8|N5FYnwz$gPfOoTCGDr7)ru~eml4_ZKr1D&&E>?n)Dl{dZEBc9} zUSnxY|DQWSc(wkGkee)pN6IW;6WUg!`|42OC>-|OM3bo+fpS&RMO%d8>%+80*7~dP z({B^uTkNFg6NcZ=JFrfI31eYEaEKjk>tq$i8JptRxq6xnRmYhIkXpzf~^|fUP>_D7*P$=q4D(Sk-l|nU&3+4+dEeyf> zI#AAOgFEtcqVu0lG=}^&?SEDHB3U}S%iUcl2BnM!D|wC}ZHODQw3xVxuYviX#RpWM zPj(K?`9^6_m&!dn`-)YgQ#$cHhVQN9;s zaPjMh6LJ`3I%5|4igR)mNNXqlg&!6jq!;3Mg=jT^)5^%dUaVZ>=Pfj6F0%RIbp7f$ zfArPzdsmp;R6I6TynTRw7EpRdPlEO)E%`%SMRG=o-OfgWI}FUYU9MxA0C6-H2?WIZv!OJXyM60F}xZyzW_`JY4uZN@+z-;=@dT+P+8+aR)3BwPv&o#Icn?< z@&DpBbzb42V&qA8OMr_nJS9*$=_&cSsv5z-%pL4y%=qT~t^cm!wL_ z54L^g@ll6Gr=j98#~ywC>?QZL-kS=0x4;QcX)EmMojjzw0{G8VeJ8S z>zYIH-U>N{dzg_8RrUUtNtU2*SL`WYz_xJNIWhIQgKuNPU245N-{RcRDFt!T2{gw} zZP2`IDgDB%@q&F2PwloK@RtSLb1&4~m6~7n?+M94fo}MFm_*%Y-k*5a9y=VUSC3#? zNK>p6dAMFTIyxjCZU2bj}hTOO4M#EYg7VVWQ4R){nU z^~wTKN$(3@v+YNqRmQyq-85lP!2|aE(7sK45}b>-->+BfP8utq@@t|u+RF3e|BH0_ zCM)dyLAv(Q@CYHET3Yl(W7#VV>pr`enAxf&%AqALs-QGoVaCs|jJ{*!ca+>uCbxft z{y1f7todNHwaOu9y}5rs>^xM(NbPc@JH)Q9>qlVpf%(iMv+6P2_|1JRUA1&az5&u&d zGTmQ;aTNnl+W4r>x4LIsJPI)(p5Y<9CSIZ}_M+3NXyzmk^nDm`(o(0=p_kFzTw!lB zo$a)^D>Q9GlcC1Glq%)g_3DU@<>M-(Zu?1n;ww)U&|>{SMeMZhOLhT%>gVPHT8d+Z zxv;X9W*5mW9#3k{PuWflT%=&;CWx2S>Vh#i%i9ry{N)ho?SW2a&M6M5Mf=XiKWoF9`K%7whbjq=E-!b|JW{3 z#I266uHB)gB@6d%xC)lDIB!+$pn`Ui3_LKUTuaV z65R`@Jhow7APs%zj`!cZah%aZz$BRG#8<|f-i&XK(Wzl+I08iSi`v;fJ{0wC5NxuB zB&^V;qnDZTIl`3$I+l?Hjz`?W_7c%_Kji(++W6v;U9kbnR;_`uJMDit2X@8Hk2PmG z{c@~a0G73afsCr@U1At@!w_s~$q5BOu!mB_lzV5vPf0#}5eH7a0#6?GnVDk$TH--Q z^Xj{T{@MQnlr^o@-&x0~SsD_e(Mu}YC&X0zVbuMC-8{Yp|EsnCi=HZ&YNWqrK9r2ymamv3x0s2WlMT}j;7yuK!ls@M-F zw*^TmEVp94^!TGWE^vx+B!n{EgYTQIb4(+UjnAYb<`$bJ;NMxQ1xRp}-$$s)vAa4ahNY#a$(Vn8hrByA5-dxb{S z!S4kwQ03FnQa{wPL+so>uHLwvA^i`IwYm18FbKiBXnAh$=j~{f z;gsdQ&_?t+Cqe&V?XT2(IA9K1DH6`5axcqFspheJM9ZE~(U2flj`p(5-}^3#Ht4z} zAIWkgU{w}se1=59A())x$&VPootV*{u*$!qx=*PXebF61hxrHW+K{4|;a{p*vX!hx zxLT3?B`HcRMJ9T-G(_mg}Ef!BXykb%s9BjW^co5Q|Vj_ z)kBfjger{`QC@$1q&O&|N)TM`BsK%A-uiWX_Wg}wq!|}6U|CV_bsMv92fpBz*d8T1 zG|AbL#&au^3rWJPq@t1fDhLRfW>zz02un&|I7gSGH3;M)CBn-~W@ms-FXGv3A<8VJ zKD;2^QjC$up$Yt=oZxRjX|-mj?D?1)e`+YzTtH@({eS24(W3p$oh^TWnDO-Es~`aY zTTYbvMdhGavt=jysOz$UMY$@7&V&!CGbkK5_v--`;Eqa&4bZJKhUqlY$L&6em&#Qy z`1ElWrnp&?x%(L566UVkxB?Vx$athCN~(h%kLi z9);nM-w%p&4G4uQB|26%ft@sk9Vv5smv80qQ(wQqRvfaVo2Yvc^N|A6Q8(G-#@kE2vcq*uEw@AKPRwqOUKTH>X zA%|#W3TrScZ5H~o4~0Hu%Zb&DOXY!nh$G%oS>Gx};_h*m^PGvLMer?nL;i);5Mx_6Pax2-7mc^ZJ2Q1qj5@w z)3bTG+q2sel!9A-L5C5rk0)z`N$hO4GY)i6rxn)+t5HdZjwrfgh_tuT?loVlkBf?#6H|Plu@mY=> zC$f!r+$=`ms81e%3B#hvh^Kku^olJziJ}#V?7pJ4efvcJyh>&JIIFS!GYxv3??B^ zDWD|DYYI;mhwc==jTE!89XJa{+r&%1+}ly(A$`wVu2ztxQkJFL0d#VF!`h!&fPG*+ z4YY1E9*eqFSe5+T*UKk%ZpCtDGbFc2yg`M=aS;RKN&dGf;~p(?6p?i^;vb4(3X)bqHT9GByTpELGH!t#4*g9$2O z0j0Diu~KA@sh_CuRhvcKC1MAA3K7^5^s^D}LLGorm zqJ=UFLl-c_g+=IfBV-!dOCAw*KF0_0G%&S9inr%dJlg34Jehp zuhZd@-~gtXshw0kI0u|f48KKo&usC!zVp&@B0~8LaU5WHQ4+K7Y6Y8y z4)s7kRrmW042~hHu#Cz5<$@a;EP_N!l|I@)>Y`D<2__XYVM zvD#&G)k^L`ul=~S4x)Bt+>XX+ocxQ-X*iXjw_8&Ps5XoYQKjmTR^as}9a-8N|WHzK-#D z@$^=72q8#l^merLQ4EB2>b$xV2LfbA(Ty zAIZexN3T3)gDRGAhA2nTU$AuR=JWvm@~DuWDb+`Kgyu{AfagAzjF;-tYe=;ehIY(@?igOz|x`#bAhDyuu2%b z>5f>YG8`8CA#zcuCLc`e+(4w*DIXyqnYOe6`$u;7ro&<(tehJOfjvJN`<;%QQzbpX z9t&H6r^uVtTC}o(JCDl2LXTa?Qc z0OM)|wh&{$Ep{|{UU4n%JLTc#oR!qcvg5z)yS-yUq zM5+2Rw)Sx%|NN%DJjJZY0u~Ue%ca}5BO#la+9Jx!pB*z)0t4>|N8pr#+IqWhY<8NW;L?LKp+ zJ~F@5i#b#trb9piMyEO7^XoWc_D2F0)IDN%SC6u8JFL^quhen0KaW-y#m0v0a%sfg zbbp1Bj9>+DOom5^V;farv+k3rg~=KXeqe&h>&)1&mK_ez~GiaEf6CT6)~V zg_05yp)KFf5g0bn#ZWviy@#is9p$loMZTaxnJtQ<;{?Js{v;tcc*M^3A>sz)e$qTN zJUo~BLwT3l<)n%ssMUnXh@P2nH8qM%Zz@m*z{+J+g-|EQ16!BC`~|ayryedLb5~99 zrugeYB`}LHSxh(vIIUQB+#pPE&iLuu;-&jfL*=&W(Ta(T-HCiFBB@s&ZRkWKQ-_|? zyj%(En6WJ31Hg7XKh#_O_%Jk}OG6OfIr$*{{h#VEl4EDWFU_p*^8`Y`6RSpA(*Ldv zD#*CVQWkJCA79tlot-ymox@C9fOcvwjUsT!hyh=eK8t5d9z~qTr|b)pHtp}Qy;m9z zScuPs?$5Tna#&T(uZ?xquJ^ofj4+Xru0v*H+R=yoKitTg^zjD}!I_$g9I-sq0g&gg zVQ-08= z;-XMPn0%&@Mn9P@BatL0uh)U4s*_`}UBRbIZ$9K19LQM)e)MsHYVqk!1Ms`i0PDM& z{VTI%niBm%hvL-voN`K}b-MKzD=;}C>Kb7^AF$IF8R&b4Y`fb8 zLD(ld8lOfNnz%C7-TeyZoP7Gl5;`CuP4zZO>_Eu^q~JB}5e&26_`$rADsPq^B9V#b zbe$0YsVEmXeyLjDHc@|kFeLg4{sfJY_xadu$eQaqTrq|oHX%;LVI)^m3~eL~*U-}! zXKh|hL*&2ECyD6Bcbi$hOr0S9ppk6f={HcbTo3L4POfo2u%m{&4{L(pWV*ukQ@J(?_b$a)~4Cy^|ygae0^M|*6sSKjB^^PuQ)5RK#k=OnPVG=Qs z!~T`fh{mLMoVrd)BjrI7kjCDNPX~}PL)X37BbPKU$|Pu{aAj9CyJG@R_s2f4nqd!p zucoa#4pTw4xT5T;*4??(EgxOhmX*UI94;W z^h8YEmWpKq^GTe&9WlV7VeAJ4bly)iVH;95H$CQVd=V{!tC+DwEpyDBHTvPad^`NA zKTQQSkF4TwHQDp0Bf%=PIUxe2rAOt7DbLHM$^OhGwLe+8cEk>mR6slHi-#kNdiZp8 za6T!Uh^eW(MWjWdndSm`oarkHK5gh!-zUWMI3hPusc=U3rji^8jQJ2<*T$AnH)_<; z519GP0FMZ?=G6#=U%wE1G}H5Xm#ACD&Ox`%CGQsToejd6t5egc5(Ef9>@GDX9%wBZ zh@lQ}G=_l<(1))GKcvQnrqh`gl-@cMM99T^d^D;`6MrKCt6;o_jvnT=vmT{yjg_yg zICVatnRJf#gK?em{RhLUDwnbpUB$!5Tcm2z*wnR;8;b_A>2|8%B0T0eI*WLR&xdF@ z0o+Ywrr{`|F;3Llq_e&d0s#x{v5G+GtkT!dQxbs4CA_v(%Ai}MFK0BzZah9B-CZdmli#u)0WxQt7?|X?>Kg^y-d7dgIc^k zSi97vng)~PiMj<8QMLN%I)MHgee_I7T_xkr76ES>ba<4KC z@;jlF5Obf6fRjuGFyrWQ^ivTBv%C+jy5_;yT8iX9)l|B%xtzugX)T-TKb0uhmXiuV zoS^xRjWLI?G39foWuPa6 zK1FRQ>WR}!<`Tzs>8^QD@4LK$WK*fGp3dPDbaZLAtxR)nEkysvNMO=9uA>#$i74xq zea2=ha+cL5aLsoRbOt~{r)H5m9NrwGXW~9h|13(%7tU2QXj$AH6T(pJYyQ((y z0}(vCpUq>z zOKZAq#SUT@+b|^x|4{WM0CAGoC&ST$JzrTIy|aui64l3Ls%2`MAm))?p9fTmcSq9( z_<^=22OWzOLtSzKjF*_grkz^tiC5y~KMDDJMP5_S59xns&foPUppCn@IYOy;=t2ai zRe6H_O@of%eg!k~vXrSb<28UXj)8zt6;<*yuzp9~x%OvjsPZBYdKJ^l<&1=uX!Qk} z6U`WGq)*sUR2|EyP!ab#uvjDRrKPWoR)6ICx>UvRhXIvpOAO0j}F3UKoys>jI-S>6dRm%?Jh8RDq@O8dq9 zS$%}eu5ugwfof@%uxJEs&V{c(=d)!bHuK#Z3mubX*itwK1z`?-iO8LrC{O_qUk`_d zhE$?1;;iYpFeU#v1~o5Jp7emDDk&*7Pi!HI4)v=hmd;D7E*4qw7vZ=l%qNB9gwm)r z!AHT|0-KpG;^wu--P(wUX$0xm1umf-2PCnbzv4=wEulZsN+ihW*a94w=CNi_Pep>> zngHTeo}b|bRe5joDmTR@%>-Ku{;?_K*n}%wWwbvs1EnP=wL3rG3oEUba68dLkQ3qu zCLFUjyV3GvO6K>U-+(rD-ZsEnLBT0M!EFFCau`8$+3?6$HB}FaaiW`)y*kA+X-+KQ zXqB`0H(Qem}r`9 zQ+i&uDYWHu5kE9tHPtuFqUJQ&Yfb8X4(m%UKa~9&I{}63 z^M!h6skeAcNzjM$`r0J}Podv!lh-QztGAaWt``(9scp`KS_D1#Y3~lV)=WUsG46b( z&`ao-^50(jI8f!6$NSYBBtFVMC^c>aoouM3ZtRBi&?xfi)KhjW08wU|EdbbKODiPc z6w|=-Yvks)8C9WgoUHo@hT$+{Hn5PfPrYOGZw6U0U;z0rW^7T0sAZ>#T&{?f9Cm{A zmOi2e)V2A|_zn|K$*Ed=dGZFC%JX-TD8uLRXWbg?!4#s@zk{qqd(majdYr!+oD8ah z<|lrQWq;{P^ihBhz&|M(SP$7ZiG8bbHy&1kuB1zEF*e^*+`sf3TH4E;Rf(o(O%*-9 zq#Bi{P%?w=T}`R0kfHp)^GGIBsl}gpWYYE1`*~=5bLz0c*8bSFsioj}o~`FDKP!wP zPnR?2XJP8dFOcePF5lO1B&esAtEWSaeHhLfkfnyp} zF`9j-gaw?itrmnx=CE#5enR35a=KDj_H{{yx||V+g9z2wNwge@3lftdPr`C^1^6|Z zA5$}uPO$eQ8YPk(PdH#b( zY&gvadrO1_T$0KHN8g<5TI?X=L^4abrhQL0+}%WsjnKrtAGn_crc;plyS|N7=P{dpfD|8vOLzAQ@1= zk;LauN1GTg17lN7WcJQgM5{j$R@?nk{K0^#C(k7P=q<^UJQ_9`cM$qOh1wnZQ$5&CZ$HZ*TeY~0-tS&Tl+mP=!tz@b zHUOC`7Is84&r_1y8V5-%#jK~^cT8bA!HjN%p9RMDs*Ey!3k{#Oy6+zf=@pnmKUC%? zX~Fxqk#Q{-9N9wloVuJepbQm{5<{pU?jI4TM$gC}V%S=%2n`6yf3dX!ZH%%+ta0tf zUrKQG_c}V(SaZzVD3A?bXp~5DQ04Gvy$o?$N}zGqd1&5yFQ`Ib*n7Ki0z2^fa1+0n zw|%Cy&$#$3{PtPZ+r1#FHU*g_>11Ir^&}NXBpO-LxhT4;TYxzX!wg`Kf-a+?q2nNR z=BIDAOejL7aQgKdA+90omXfrUPVU$)wPCl%zHTJk2+{#wXo9b?B65#Z=ojp!*$H6g{eP z6W?7Gk8I57*Nd91)N`H@v2Vv5GD7}YBrP?P!$SR?K?1q`yF@0VciGOb<38a>zjA`v z!}mMVqCi+C4kT%)O{B3Ya#E&nDF`kSdF`wd#20Zo&RwgC+N#DB;C>!9uS+bNvQWN` z{}CSp3aWeRDmb{4d=RK6AXkY-TTLg%s9ty*xpzK7zTGtOI<`$@8hOYqH?%;VDs`DNvlZqmD%q7~ZqZQhd}d>BiCeFEAF{ zb3=y*iu^$m8=WQ{3(=uD1k(okH~C2yksg-W;?}k%rB3Eq`#8-Mwh%bvM=ctgYTqSX zl)hz{oWwPslxL!!05J*KyC67-?vIT7(7C6RpV_pWw3h=Lnug!f-NFK=;p*R~P}A5L z$YVd|EN*7)%15N@#m%Ky9sOd^?F=_i`FQ>y8?iO zIO1Fi@9XF3!yLX_N2)&h3`KSr&xp+?uTY~PRYQ0=l{1;J=zSC_#FbC%~Q0z`rQB9%OS+Sr3O1lkt2Kfo-`VK$r74+7%B0mSanRO6T%brwKeq+9jg_W-d!{7|N7)jQEH=FgF@~UTVe-+>}v;D-KDjv2Z^d|p} z&^W!>c-3x6W#|147>bs}=KB!<^$zQ0T(I{XKS-Ff_?5XE=rA>pq{008kD@krX zBUqSn-+;TL%D!a?29u1&uhoN>WRS#!kl!_ZNqpMwcIJ$;t&=9kq=ohP#;5>5MyH~3 z*T#CHBNP5uj&eg!#3Ss0G_!Mk-+ zFVFo+mxKV+Qfyo5mCmscxI+^xUw$#T--eETz> zl@i{lpF3GnD~(%de?i}ub6{Z?kvXmUr$ULu)?S$WA9bVaG^kLUD|vj_~jCW-6d#dri;`Jl(B zEi3!xg=w1)yvM7HYDNE&%qv@gq>u0c z^-+pmt6a^Dr5|w_lNMcB9l2iV+Q}3YQS!EM3V$4rECxBD%~q@zLaz)-M(Hr-URE33 z>HoEsiH4}*%ToLr60&VZJ$-@N4Suoi(AAg~(8o`r=mycc@pJ8XlvJO4{8Jlfbd+D9 zI0UXmNWSM*t*lceY99ojqM&%OxFBb_&`sjRoV23SFqorobh?xm5GJN`8JA1=De4Uu_ ztHp-5M`|sFTN$&O?g{;ic-urGHy0xg-FldzW|-LB^w`G8fwrAx&!3zPgw|y0L+U9M z-o$r1NG37G?qnk+RdCqcg}RkdE{Aot?doieU46LrWTV89NBttGOp2q4mSv!1ZFj$k z+h8)ux&W4qc!9Yc4=n-4n^)s1jxGLG%|f>+QV}>XuG)$ueOjvef5sXwF5wEk7)ZI!-%$FmBY@cXTpBFdy4$K7O8O^P_&g!wM_0TKur{)G||? z@?RtPb}|O*Q7BL~D%(n;)!(c3Fv;RJk>d1Jt{sYd6TRV~_||3yFLI5?Lo5r(Xc z2IM5y(>g*{PT@bX_nM69!tthNjWm^WOxyZ4D(Z6xXDD9~0DX^;)z=mY7tOoE!cd+Y zG|So^Edv+2Me^p&8*Q1ZY8v~v&r&Sd@EErkC-r%yb}D`kIrm3OF%WdFop^N;Wa?LC z#~su-y>`ZgRXAtzrmDV0sm^Z(taK92pE z!0#`Wq7PMs>KD>xflR?oXg3s~7Pya4nxSF_4YX*ND#o{H}F0hbU&w8_| zml&#tdJOKf{(3kw=>K}dX?s$;DPHY9P9-ldVmJ{Jnz0v1^bX=dQU8Uo zVYu?khh4kXy@u=5ihkW#&D1!n`?{;2=oJLZkaL7gji~?*c*I^sLdR&jb3PdK{2oZK z)j8h8%X5c6_J+lo1$Kj-v zr1AZm^i;RO@ckt|q(m%KGHPButNpFYu&@BN!v4j-*(fM_Lljnmzw7k=0=Qb-Yigc; zlYBS2z^aS0v9%fDeOJ|0!kgfoAL3E zCcVyo&?0z?1W>s6aiw|Dj`%{uFp#k)QX^+DvWq{E)fl8kiu`7;0wOaZpVt#Rn7L)1qP<*}h7%RfB!U!8w$RcMfQefoi-oV$%tgkXYKyVsCpf#m76 z)^s$Ib2AX-Yq2=H@oG*>793IYHj@5X=>F@((5}rx}s5J z9OR0&6AiWmSOy0605U~4O5u;#8bf?)Di$v&#Db}H z438Mwi>J3Mg-%mHLALz81I(k=hobpFu zIL3Vev_zI>*a^@WI1D}+LUj#}$jE+|KCTF>GpW&@{xVm;PO>G6fa(xVQ@wq+glg*B z5Rlo%urhPSqzs3D1->Hx0O~C?k}BXIVQ&Xs=9Is1s2YR1pc2^)C^pwe zG)Z+*|4Yf$Y>Zz`%^?wBt91J^mu5^l6;yvIfH6)d<^FY(`H;YC{4UCRG8t+3m_)>V zE&cCBd4ghFgtZq}YQ0P*z2X^4zh@u~fU(G8|sl#$r}GtzqyMLfi_2P{912hQkYh~$EdcP6xnLuf4 zL7+twY9(CLj`?quVaN_x5Gd_;In<@!V7=6U;>>FsNrC@nbkp0JEl@eFAk(9WAi5V%YP`o2%B7iQNY=T#~wv@ zf!I-DOkA!)R3$5w1a?^U(GVW((9Vkq2yzSg;5qVfI(&BAiCd3VB?u`rK#5YkYAGL` z!MM{VQa}+rm{tYhC$gqJENJM}JWNHSyCHC>hj;}H~%et{mRoNGO%Cdd+}uQmi@ zAx!DtVLiLpA=t*KX?+l`Fx4=BYA@4Wrv3x*{?ydp++BT%mQWd82xt%l0OV!oZefEQF&KLZYhk%LzbjstVR_iWrG)G3oxDgdw{zYwJ zo03u?2|9KKh+i=}!=ErA*2qM}4vSB|#sg~&_H{j3Pr}8WD;#Y%q32bj1Whe|H0?n| z?z}y`S)QjacrOigXQ)fxCl@`9ylGy+FHe;-N{0jP$oIG!&b7LY>>fgCra{!6x_hC` zRn0KhFz7C$wDjLy=HG@Mr-X|B>-}qpRrQ01Cw!-eZ?gkuSN{|u7;`zO5=fgz8y@7T zQsEsWsX5|H-aGPe648{ zHxmm>Hb>Q?SQ8W4Yyok^Aw3B;Y)p#;Ww)A>PLheugo~J=&lX8dnloZnw6bFrMs%Ug zH#*%@#&;p2X`sXwW~l+Vfv>`u+@JK&k=(?oQr}K9o4>q%Qw5(>02RL>nN#q*5B&{g z4_}G`)x6T*sGdZ6g((fxw@jIVJ~GwDl6*s@xpG#BDB zjB{LDHG$aqe0$V1SK=o#DS{)dk=iVKYmtxn_%{W{~8(3lY65r}MT#$SD~ zH@V-#v#Lp*BBy<14zzayS{-0gyrr?ZI}9Co4d3hFdQm^Ik$U&|oSZM{*+xuy?g1Z| zqpt8As4yT&3j4XgK`y!fh@3!?i|d2G&9XfHSvA=ShQ5w7t@4Na2BuYKI*F#B0ah6& z%he^M3OK6oC{?tQQiwk_851o8LYM~?06eU;vngqACbVH-<~(>QSY#eK3BcE%#Hwhp z-(w>ArV!@y#Zj#v2eY^#Y@~F2$=ZShttc*|%`2okh|^C4@)Y-BN~zTPt4(Cz*^bU2 zGQJ3LJ%mhtN1b0J;ssES*jtuhU)WadFrFbH=akC4bswnhPo6sXxGchK;_)wyc)Mu9 z&OzoH*W3m4=~ZF5pd3^Y19YCAe@c-;D%`=Vus@}!rAoD-gWjKb)aHY1Q6$n0?C0!F zTZ-6{Vx&uS;qH5`aAn z5fS~0s_o~YC z%;XH*NSi(dq*w|@{F^%Mq>&01K+1gO2a{aH+f-=cN1?Gxfddt0z_;2VqW2%KZ-+zA zt#vfyVRvFPnAy)UVkA_BNZ=db0f?Q5B_e7abvDDS3}$8+!WI{{gZ#CHkD+l1%^a}k z>4#;|qY2Y6)UJC(Nh+U?=Ic%W3Acr=Jh884JX`2be8vij3U@-tDhkEvCw*_eaqoct z*MtydjP@v8K(EK3Q?w=#EQZbFUC#|>6T14amQ(09{hOH1^2;ptX0`A8*kC#y3bAEF z0O+Cq`&Rp=!Szmn8k>Iv_WRp|2-q0@24=%>#3xmCVOxU8wGxi%Y16cHzS>2{T|FIN zH~&n4T=H@NA9@!V6HN%392{YBdKlvpOLd)C|3N=57HHw0*w@k9-kJMIn72_Jpco1|~!-=o0 zvKEQsYtqmp5SR8!tv>_GgM|7_8pN?iF;kNMlJz=snQ8&|A#(y>rVVub{hQTKbdjSz zf$dE5;1MmOb`JGdJC#!uU>-ll)#gMxTeg-)E9q@i_#$|8Vi$jb6py$(~IT`7{Rk;7A zw|z9l`O74F?XJM!;N1#=3fHd=)9JJ~zYEv9%8m5jxW}tj(EeRLc81*8SZxfxS$u+K zZlaq@=e;E>&M;~!kdcfR==uAieQc~ioHmq@n5tx5MSL~=T2`OhKk?H>tv8e%`J8*B zjLY&kfhg>7!o)@+s3wNvcmm#Qs?!&#IMfez05bp zNJOpqY3D06e+C-~9=zuiUM}mMDl>nVA%)3S`U$5SE67$69tOY!gVVAVh|xU)RWSuf z!<|9X8B#;j={A4?sE|TIrmh_8ALF?g2@6kMV2f#Lm>|IpV)Q!?0^CM#D7Z>1%eGD- zPXGJRWN7e(7_@+!#BIx*BDSN$4vps`Pxwc}mL;LS9g2?tqUVSLTKG=S(?S7@x?U*e zgQO-JpjKyj=YXMz^6h&kE97=MgQIeoPI=G5)lKflVD5x#b=7%LGIj#&EKZ}w69aq! z@=_3Th>afCUNrtPrz=m`Nz73vp36@LwF2-MGV4jY^?6|3%NX~J2PV5dTBL$64Bl;} zU(B_4$ME6d$WiHDlssJr0zg_CG`94+>}qz9D#>X;5CHSjb`?9*!8;B=vnHxZW=7t) zbKX)kLTxPaMtb4k!+1V^%aPJ>To+ihR?GFt3kWy*TRa0 zdO07mGOy?h5YSyqB{@#QX;G==OiBs7(K7B%MH{|sr}D+nlXoSGyB#Uta~nz1^9uC? zz!&VsHWxI*>I;FT`mC6AOGIhhiad`!{DHl|Ni-;9clsdQ*!Jg#)=?jrLed8tOPs== z$Qs{qsXx*(WtyYO7$%L31W0@3SijROdbK{BY82puvU9v5{(4Ze+Io;YVhwdlVKyB> zz)S#e`#KWR>!)e{jv(pW`|9GM=QS7g8W+y;5H^Ku^A4Akv$8=yvSM=fd*7PErR|h4 zJ2M^WIkFzCu%L@Zacg%9vCjU3sbNR<=r7ja^d`kKeEHIi8iPl-%2HmHO(;S<8mQjq zRVYJVs6`xzYNT=#yto=$6&3rM)wXdn8i&96ClwXGW$i5ktFfA@KFxRoAVSv7VGG|p=7`Rw5wZhEGcFl3uA_Ed4!>>kBRe8nENiPVV$^3rjrWroT*S7 zahCHMTY)Z<)&jc=@O*dK057#pgk*;568O9KUTtuYvEXOo+v}y{l9B5`8?y)@(Ihl- z)=WRoBc*t6SNihH2-nONi^ZwBYpvjXy=LU6A6I)(cmG8w{@lJmg&-HZs#Jbw3O@*8 zGGXv~!v(neLaP`%2Wk7tIxNYb;Z{^G

=*y?OZxYMrG^hN}Pzq<9#=p!(4419P@%e73L$Joq&J?r#@Lio!K z9xhP8?cibG{Q93&dG1j2ooPK8ntXTFOPm4t=5kSt;z9|ue=*PIFQD9?SXtTBV4pi$ z?z#9&0M=9BG8fQR?v(_2x?}-Pzk!oDAuB{!9@Cza)$QynlBz||Kz{J&vP^cKvh>_J zbq@f*9}H1Aawp0WoX=vT2YpJE|4Jl*!0~jlOrp>wg|4Bs`j?F&iYvugSNP{t=iv{- zy0nk$%F@({^#z@F!DY+-LI6I_o=*%QbfZPiR0fZxHeI*xlIr8Aevlt{dw}{+x zN$GM%U!WbSB9oHd291NX?KI|?sXaMrwpS!rxnBSgcm^Jd%UzJ$I846;h;;%5tjg>; z!0f95({7gYCrId(yRQpJ&r!zw-XBW=X^=EYBR(mMw%u{cvsQnNjt+POJCe7P} zG>PEv!$^c@{bmuH8CpMO!}UZA?CBs&rs!_hA5Jg=c(6n9?+^E3l%+_3WTBY!?DqgO9@jN2mh)zxdG(II18 zP`42NlzxmPAOPjxZ9bC~V<`(0jLoU4vM>aa)U`_tbt{S>?x4zVTepC(1kvQW=6^`p z!Y3g7+bz+r|AL5{8l(5Ko0q=VZM~&D!81v8xnq+)6#V#|z#y~yH$14cQzU9KIz_g8HCyl++!!!9&?7t@DG{PtRAroiMBMhdG zw~B{X(nn`1ad$p7OQs8)6F#hY(c$+6o9%I~T}i$I6KpdxtX!SYP}C39xo~fx+FAIr z98tcDGMfJG=b=KCH$zcJ9LItWr)x_q^x+o*Sm@am^7)^lOR<%v6-#S`xS~OR8zK2d zU&cxD8@HvVO1B zjIM@_z-{PhXhc2=mybIt7f*N*BVR~SKe{ntykhyRrS_^Q@k`-ck5{d(Hs?!`3qmGkDsz0f9H3lFW=@$XD$=ERRCNVHJ+(18WpAnuslA{KGu>)w`aO0GK(L`NM&)jtiDZq)shODo-nf&uV5ol_P3O_~}oGBkmE zTG>uW65&4KuhioLUc)A`ai+I)YJYtmJnjxoevBGo`>_nn-55yuiir4F?}0_kv~ZwN z$xheQ@*mA9pw2{YI@6gqWt2@)i%ZNb?=Aakv)ho4ENHHl)?oaXT&GwxM2v^O^$r^U zzX1_`jR`9L{{2a^05TZD(WWzR+DbaPipH1sVjHtMmcMb?AvGrtV;MZea_-x-rHI<9 z6~wRNeQvD}5dq$8aMm`1eM*h5aRbjhq^e3b#CW7$b)>g2kUAj*`IwmG?1$*Bb4Oo{ zR|@;Y9@6<5x0^h9Ld;PS^ZQQBAn|wS+`ndhKP6dn$!VZY#y;LGrXu*Yq#*U>Zma5C zaN?JyrmX9b>;9RMjJXZC<@_LAsN%#)kbj2|^L)ob8J6e~C6#aiNz||mIR`_Y{hHmg&z@nB z_ttUar`Dy#=f1gSIIto_=0~9yJm}md>lX^d^jJ1nPm&P${t&v%XM^bk;pL>^oAJ{hMzRNWKb1(I63c7a>H85(7Sow>@rt!!RB+_*VJd{Mc%$@>#SUApIhA-(fVvzx-JRdP(a(W}`NC`5EYt zojMLr5_5Jr?RU+=Js2J4voD_oE9fl>YF1f1xhj@y6ah3RVA)+wot^PGsRT2)0xIA# zWE+fk4@K5}smbi4u!y;_GbX02a4Ds)S7`9v`uZe#yn;YSHSlMffxs$!APYhX29!@a z?Ju31j!@}i6sns>8BabaK$whEXbNHT{us2>n+$r-a2rhU^l8G`hA+=db?y=~(WhMMeP} zkphNb&Qe5t-hGOYUEHC{)3bYl%3pZndrpE_EuG*t3YaqS%d1Jy$)Pz11GLdHqrC%H z+2fdm*%t-I`#xUVJ-ED<%LrSgJq{AY%4hss6&O!tVk>uw4tras1bAx$8JqjwgBAPr z72>e-9jzYw56_=UM8@0DUD}(^EGZfWgDTFm!*utn8V?JuI>G#XI$AS_>=eJ(tf} z&w*^BIc911QCcuWBkhQ2KUre6Gv<*Z1{wd`qYQ8P!qN}uWuNC2yz)yG7Hp_BTXeB8 zBO1&fskF?)T6O0*W(hR21njvDt3NCiG0-t1G$hl@#A%>R#C{O2w?=ER)n--FmM6U0 z=BzqgV=;Sd%i}ayreO&umeAy^MBv5pMw@S{8lGAZIZTYT;OLy38`pJ{5@V_+yDibNt325cl=P)g9H$+;f{6V+(y@XK9*0c>em%aA9b{~s; z`C;7<2^vdtEX1qz#A$Z;C_H}QxTA+a!bBXWtsxbydL%2rBaNW6T(SE2x}<=E7!4Bx z9-$D5d>?FG&Rf=`wlJYdyB!(ega7=ZS*11}6C)e&O8Y7I&6+QXQPw#By+IQ$WkzQc zDPi--UDdEOXJR)p!o_R4BmfQPn~Atw6#5q@|5ja!BRC_pW^u~IGflL8B7+(Mjnx_zahs49<6ne z0*#}dN`Uxco0-oqYPLM@{$qAxn+{XT+;k(9=Zdrxz^cQVei4z<$Wp~qVJt3#G1=`& z#1PBZD{F1wrES;Bl+h>GYb-jprn!`g_^=gK2TNIH|FgWjBT%p;&(}mWgpfsBI84*8j)SvhrXn~i^qDoB?9_tEih?4K!<(@a&Gl5# zm~i=!fL`PK9Ju!Anpr=MK{k!(FC?*-3V^h;-XMpeN0a0zv#Kd&Y)rMk+%NtEc-iz? z@>zloI=Y6{q}G2uQ{LN=?H|naQ5$Z4=;Lp=1xw)si~I8o*Q-KO+N}2Q5qbU{rzQLp z_m4-*O2va9@=;>2-oeRFk{eA-{8~^+fe4gaNtwKHemdHK!UnKIHEWN_q;+70^TJrW9GQ%A?Z?4hZzsjBAgXR7HeC2kw9^JzE2~X#rch z8PxnhXALWPlGR>@7<)`o)%dX6-^1vDauiS5!cx1|FAKvYFossY`){Jc&ZH}Y>7~)) z3yz9jjr34_qFYXBMWPd*D7^#^9g{hyG>Tu)EY8?_9*PfAxzy=p-gJLR&LeJO$|bma zcN-6+e`zpTRb9I?F}$qgkU02yY86~Ft2KEt?=|JS#ypdZstdpKP?Zo4qr_2bA+=~W6I`q#GX<}!?7>mKHXmOQ zyy9K6(m#zrPb}=r4obi6NjYPHvqKvN&TJe(6h~W2r(+o@kxHy3P$eUgR27alUeF^s zg^8m$LkyKwpwhA>^RG=+(a*K3tm`=ns9V&}uLmz1Gtg8r&UXK=7j)FOXssF0YO)$Q zvS}of^x+d1$jX4cSZFQQapq3bhwf zEk#Q_z9~~n$Z?jfd*g7CwNPSI5(0vha6JI&?HI6!B0PW3fjWX#d*-ndh$gQ)b!2&y z*d1?GPk$pm2Mtz65&T}#{p+9+Q_`CCJ)>ABUet<+PH4Uj-&ev2joH&-qtNe_Qz!n` zU;Vor4gRAvHdL+ZEY9A~>IS?gBimh-WN*bZZ&5;wgp>c$fbB}&?JL(814N~h`4O6! z9uA{z*{u=ZiU6;3HvXfDuPo^Pq=dN@r?fB zmmx!_{bLMZTID%c*#BWFfnn}H_J4-CNQ!851pRLrD&XnEWwLB)5czd4G%?Qd(7WwU z!^>0b(Iv_>LLDa&Jvh243Zq3H;#i;hWbHkT#CNYFYtyVJ6~gpxYnT|`y`d`TI)_(Po zxD%&ncbu?Kf)N+q(Qk{8KT8%3RSylV0bQ*R zeWo2KOeM&7|C3p%w?)zk9u1THVV7mooTo&kuTP`mH)q+fFTT*N?2BLdRvNT?sLg*v znulZjnBN1g4$R5LSosTlUXta#agg_|PzO~L`7HjJ6FGx1H$)LN%wZ<00@D)iEvjgW z|B?`|OoWDU@@V@L+lV&U+t_c<6^$$045!;Qb#d}D5ifD}p^|gTZi-xKZ;A&U{l4oM zOa|6>R$J76vljT-=g^(d(*8v2b--gpVB)3Cv~@PTJALKzSAJQsCsymTdgM`o2*k7; zsD|-jG)aE7de<%2q`jj5vx{Bx<%i+sdVG9N2F2LV(LcQ4>=++u3>o+6-;O36eov=t z*5y7o)`yGdiwt)#ze0(m9%>Bfa=IyhTs5-{AaY3A0!V;ezE^!~ci?^DH|)`@#HiSg z?|iTe$Y!yXgH#j#;T7j4^fDqqe4N%?&D7H_@AE- z2j}+%AObrAg^BfUj9eK3zQ=K2G6LVK*J(g@`FG47$OzU`F^tQ<^!>5Hj82{@6!H-7QL~6hp_EQ*B0`1$EIL^T$6m*^l+XkkH210>T zc9Y~J`r6=}>ZAlI<#YaEmZVm=b||%7CoL@4VK~up#P8({BFxU?BEHGM8yjUZq>br}z1A^Yx9Y zFuaohT2jrFIqo3*Zpv*y3euHkmm-@J({R#7W?Gz#`k|09=^3F-IP=bFOe9!D^H50G zR<#N@qjB$NO^X*vx>p8EdW0TGY6JfTXM69*ID0?T@4M7C_J_y?y~vZojGoGb8Rk-X zBg>`82-nk`;?!rIwk1}qXUhS!I$k&N_JP!q2zey5IB3F|*bPzVr^Gh_2tSmUpE?ha z_|`x2f6Vq`CpA5=&=mYK{J0=uyPoLt60+f1;oIcy4z$aXosZaHt` z6q+_?+9t&o$ty!eX1K@2P|5ZW$PaM%4|W0>e|}h0G|94~MlH4q^nphCQ8r{ba)BLNou+L|I>- zF1AGCiFA~=TIVj7|K6tBdR6UJcn(Z@F){&VK{--t2J!?>zyo(ICRtKHR*oL!FCKY+ z2ohlF4S{47z$>Ux!LRgzhw!9$B$dw9+&zne<}9G2*zVm)*je;`7OT|!1aUmWyK$XC5e_JWjjt?1`Dh^y=s3e*u6 zjA?VKJpY{3#ADJbhDxdsHv4-_DH9hb&*+U-JleYiFCqBVJk+_#STFnl~-; z&5r*BYBO>*@_9~vtzw4*Dpg+qx4zZhdMl??L|WhM6MzHC5$Nj7VHg+35n?T>937{Y4o&Pq)Y_gdd6Rqm! zF$Jrc>KaW(NTJoax*n?@Hy@qi|+pYc#%rS1@-~i;rA@?6#sh1Z`4VCj&zy zx$|qw)PBsn=(SW*y2vEt^nNBQmo*o36<>S^mqxWt_~?iRMpd)_9xTLZF7{P6k7WmHc~zG;+UQpn;k%vQBc^?E|3iJ& zk&GJ+$r#Wn*PR%4$cmIg9SiqU__oke<@5;5#%oDtQtH-d-h%SI>85qIqDfl}b;V-F z>GkNBC-+(~WB94AYK*)Kf`I%q370!4m-d7YtvJ)&k2l{#_bnyjj}r9J-t`L0$I)hG zhfLw;DB*v%4S`I~Kl{bF=RX&URnp~C^T{glmb8c3K>Et3#yxOg6Z7slmSmBvVw4}% z_Laor4$6KL*CtQD+`U}668(t4D+aU(64Xh_!|#sgjr$Yfi?tR-4Fz$A929zIm5Bve z?7BWa9K?Z8=t_a{2?7`=rT#1mse)>SiZwc~#SRcVAO zs4+LmoIL5pDNEh{OJfE@vD<{wGp(e^n1v-h;lX$Mg2q>No($w$S`)GJxOg55S3mtbxmj)xLZYaBS z$&>pM65%!7KBZaUjB&g~S}Ap!nAn$hpL56MCFnB)?TFxGPk=f%eo82?yJk+IkoWm# z27zmHIRyr)aUic+x(RR%<=~9x8am8Vde6^;cRzrNl;q>{9Q=H6(c5b>Z9JbsSe#Rp zZI|T!^*z0%z~uhrO?DtGf&qD=QV9cf;JmlD(8TD@M^J5nsG5#QaHizgq_+qA-`2G0 zY}9?)ZjS%E&+f9`>2^yi+b1;;PEv-agH&8z9t}0X5Io7+gQT3w&d_T1&kUI4v#(*? z<64GKH#BO${S-U(rjF`npkJyTO>+D>kFP7)28SS{3HPF187s?>H{*H+lU_t0oMkuB zwieAxyDZ+uQ(V6S3PL{tN#Ia9`?n-MYOY)VYlE)=B8JthmniO9;Y1|KR~-mTAFcIe zKsVd>PR4A80!?ljaV;OYg7Bkjgr?7hpqJTSFJ?deS0xTyM5}c*)CQ!?l_W@1S9}#e zT@k&9&ULgVEG<9D=5oh#@^}1m=6w74d{ZNW-~v;U?PsJw6~!waCHBv`IB#>l#s^h` zZGiEkf16{?A&)glR*k@$t<+0Xu^1YNgA+!o?uu{L zNZwdUULiZ^aqzCb_cZni%2;aLjE2nNw(E>*DspJ|9k3u2k&192KotD4J@W5*dy1@m zB1xmikM&BU_Y+hFti&(L9*4^IEA?YS>sMx_FUwxhYcMlV6Cgi@I&$gFb3PpY^^t$K;p_8v=@(nm!XFtK| zw|ohas`{AqS8s)AcpArtmx_pT_?+GZAe}Qp?FB;-UFnPtgyBZqPu1kgXw*NtxIWQaGoZprO+MKwrQ2PhNznez z+eKU(F47lWZc4Yds<0ib$8z`mcI$fJB0mo7=s+1y1z54Zmu9)~!59a`qsqzlv1!0A z3UDpFq7{L^rQIfqy501fnPAc`hL>KUjno9+a4~1GW6{pF>!y1?RxcZPn6U>V!D=&Y zVDllg-+wGTh^3&dWZrELm|A0wH~kQ~15|OB_ovb*Yw=ncOV{nOr(WbL4;}BnYqF6B z8@S|u5N1?O6R0G-JDlStDtX-wabi)U)Vcwpy8rJi*W2f|Xkg^slQ9H8&KD=#tw1)3 zJPBY6b!|Yrog$w+sL-`s7(WN{)5B-)&%KqgI2ug(GH2@lqw1~uqF%$UZ&K;*2C1Q> zk&w=z2aqo5mX_`Ysi8ZDZV&`1>FyRmKpF%YLi+jby|4SapZg8WAM=?x&+}NvTHj@U z^v*9x@ZYs2`l^9MD?P?oW<6KL)y)eS7PW+_$ZshSEpNI13mAvQEu3}tSIXzf#x4>Y zDMq<>ZW6p;bLlp+Q3jpNTGnvOoqJ8pbcX(7Tk+J_enWC#3`rK*W%A%)JRQOf5ZKZ% zt4{YiYQpq=zN5fwO z{gzZ9<>LGk0>?Ite#!e!H{whAd3uE=UlY&UbcVQzLThz_KG~I+X8!}mJa=5=h5Uet zHluekv7h_vD!6c3_hfk30FQ1AM9|@a#P|eDRX716=*DR;y0N!rikMOsNAN4FE>GwP zr?;Vv*=gG79gX^-tSv@!f4{T_qBt_FJ1e%a!l`hPxD_Y(UcL_~p~3$oL^v;%ZnaVx zx8G>_sb6KDrxC{AHYLRU#OUO;9R+Y>TH>po&M;J!Dv$OAI+*gqZ+_1*B_UP7N~$BE z9JX_M3{~YYYdv1Hl2?(~q}6rQqxJbyqsZb+Cl=}UaKllX<*_dzFB%p<)1HJx#K&F! za~g|NWjCd-nxX1L=OT55{a-PC^~Sf3ei1O(>7}$UTgb{nNf|-DL^oKB@~4|{I7&#% z_Mk*w)rRj^vf#T~J*^xc_p_xpMj-Pjt~vu;$l|;Sd2tB-H0g{F3q#5$B5tidMPQ>O z7Mx#CwymAtwi;zoEBr;E)XF?_8P&RUasw-X|L_&-RQn0BnLNwIVwOG{#XNmTx^7XY zS*{#t1ylP=N$C#`cBg7H@AM{W!wYNp26eWZ0h;aSJifhZqq<_~_T?20EO(2y31)Wu z_Vl3XM#&)Y!O4A00NSLvE;8l#_C-#J$6sh`fPI@`c>QC&KPSIcC|TRkk#}s|zqXQZ zx$VPXMy2E5S6*cqsXi~D5PERh2&oazw6;5_e_vzFW@w1hx=TPr2dho=4*}SGSHoB> zax?sLBj9aHKaR@c0#yVrlKWM-!<4R=+l*KJ*xwrG!~VX)z1;g^4PUG)Q0$;KVDX2J zEa$~lmG#f}bg0n_Z53-lT~CAOkR9=hR|%< zLzDM0rEFG|)FNIJ1Pt~J(tg>48qT^|tKAgI7Bb6>K%}FJF~ZRgJnCZ!CZKSB0&cbrsAJeau0)YYlJ9RnOFV;sAfE zMZ8Qs`Vj)T=B;JjO>#P7txj_pZzV$D{f+m@VocrrX@?bd2)D{7G#vAl8a}$_y6uAp zfo;KG`?O`iM>dmzZ2?5f!0&m^sI!!;mbxH4Y14*6dn}{;#^g9bZ zt@Y06k1XOZVR{`_3W~0bNyPbARe$VY);*KH{GwX~WMcS^Z<^5LOVDUH2#K!gt-rzO zN|%D@>CdmfQ+fzhpK}>R7?A#VP`kBM#znMJE|vZa*O@3RdsiIGTTHhw^Aa%2*GG9z zp@Z-;?T_)eRP+|nL`1wc%p@DcBe#hb-c4Xc$_clBshq29e*m0KnkEj6V6?#tT$Ba6 zaC8LOem>dG(BuuJt0)Ez>c7Wb{%^(1rZdXA4bG7%8y<@6+=Asrzb5?6M3fGbLk;V? zL+EX+LtpZ-v0la3&E}P>+F6CjaXRPx)D@5eMO>IeKTI zITYp3p8?~@Y@K@NP6+cK$-P(|e0&8g=9o5EmaBo1ajx&dzCWbzRKquf&+^=-lI_aU z%Y`LTJx3-nT0MTAaGwti`+qLhM0W@2mS7dVP=YWG#3(AT_;;HG%v2y`mTo1VYnfw` z3jdG7)RzrIeY`*02;3qa^a)9? z*1Mq8QZAoJF5}iJ^7quAYSHBnOYd)pqx)vv^uZ`^ki_JmY`&#^S)fAdLS0g7mw)e% zDg#@}2baX(vp$Omy}~cUhCFt@A|o81!m^qFVpUJnS{S>-ZpF}XfmJ(Y;a*SLjm!_7LR?Iw zusFFqJBMnHZ%!Ip2;fR8iJi;O$$rew2~MCdJ%&$=lbYZn&3R{+Gp2tJaVi&A4AHude_x?cfbNc4oN7Fa{FbnxR5%8Fhzj}a<$!=f8XUdE%8hY(b1)7vTXC&YQ*1cEtC3R2wZejz7jS{6cr@?k@Wri2V7*?iCRuaD5eu zW-j7TST$<<-WMe(^UK2wDS6Po<{M2|T@}n6GvI$NZ#KXwJ6w=%> z2=w7$!XR4>;zErS%{~tC`wAHZvI~x>*Om$y&;@woA7;SwX!#0^DH*?((?^8}JeyMp z55*+6iA`^xbi*X|usjTF((l$B2`d_&nxpD~-XriXM>2c$xAuxEKf@RWD4G%A2t<9?D5q;U;`1$488K_;Yyc~5K%*^C!@$^oltJa9vq}2)Z6-!|g z^o3^Mv)ilOt<1O@J5Pbnj5*-@r`tRJBB+NcIPgmh1V`6>)4EX2V7(5*-z;fYfc9cr??Y9krb@33851-ITal_T?F^CzIHD~b%+ z6$>`CJ4Nc_JC@B#?yr{|D0~=^P`$SXy21DXaU`C3df)Spl2rb>PH&a{fldVW#;XLMdVT)LKVN3^ zJ^zzj3|Fb7L2W|kc!1UnD$fc;gK1|kodPgR87++#{cS5RhZ1u+lw3}1mbcy3|9A`S z#9LUcjHdF_H#oj<_4TE8s_lNscR&9NHYNSq_@02TWF|%?gteA_*Gb1q7v43r71$BB zj8t`3kE06u{_&QhW*uzO)|3fEpu^qB_X8)65<9 z$yxr@xCARxwg8SDiW!ox>rzOIxGn9=kOlM|TmQ3@iys&Rc|Fvez>YJ3)hefs|4R1T z?q^)vIgAQb2`#{^N<5uW`E+-80n~-7l*l9D$ckWabnS;KQ2{LS>17~j(PP?}7#xzK zjvV&Qb|B*4v%N&j;JdL51AEudYG73)-XzD<q-M4|4Y-{Mn^JTR$F z(LA5aE@O{!djh=kPu=4@AZaj3Tx=AvLQMJYRC~rwj-K>s)M6qw(P#`jWh9v@-)eH( z`9+0vE*j7*%UXPRbmu`#XX`Y2Gp8;EB0Z?x5OA?l*t;O17|CpwoIU=Ma0o${YR}LgE`2d_lEe=i z#a2N0a-#&=x-Y?R_9?Q=EFLnWm`mHIxhbDO1SyRzy48XLJrO(8&-z6mLTKpfM>Uy% zP(AzHM-Eo2mHfJ{xXI3c7nn_q*MDZ9g#Ruu-+fMSglOYOgPgl_fA5CtH>U3Pap=9X z`Wt<9p1gaEwixe_CaLac0gm&*h;F)67kLv~;XfI#l1`h#aL#ys@~TMFoQcdZ^2&xa zaQ8HS=#*9#WO&&)L*zK(?E+1&)pV>-dWDkMP_Cny!xSh^y+?d{i-AB(-ARa#i=Dca zKCZGyFt4!R`*QX95$kX&i2&Dv5OagN>KM}}L*xUj^BZodKW*#WW#v?Tv0ho0TtA#x zs;bESQ_80a2*NgsNfo+xR0$${!kQH3<5zz4AC<* zyg%e?LPl1d#yTcQY?u{Z%}e)yQ2w{B?uUz-u<2CiPvNT7(@W3A^w2*^`ryxxAFF?5 z!{J3B_n>hn;_v@H#4rEYuN)qdwyB?bjmLj%o(7UXcW64ybxjvtdr)PM|2!$e3ZQW- zp<{%3;TM*%ib^)2lbT~r|F5^Z@_j2b^i3=TOd<%1{Txd4F}V(IGN7axmSa^bgu05z z@zsBlT_5X@dvZAyBFzTj{w$}JuUq77TZFMrMu|5+e z>ZSc^pqhk&?~j^X$oj~$bImgrp#FAFljeBtVQmu0hVjyK?oLB%n^P1_jo3U)kKsT?LWNK1Y7ejqHv}) zmpA@rHvtuaZdH(yQMBh0;W&=?iojqc68X_#cExz|#{Kr6gE^G(+LSt*cM>Fn&&Ws) z$@RDuiL?YO?V%@yAL^Y6R~2DPu`27%m(ip13J*9eCALwUoUrdyQ#PN^a9hP}s>@Lz zqt!0b&nfM z>s3If3KJ77meq)RMETPa*%kyUS&?oTWff`dnV;&a!^^ zu!R{Y^)8h~OMD41Xx3`af5vw_v>hw%XryDnXXh%w4_6?vnb$M?ni5Q|2t8j06 zCojx1==`o0Io*=)X!`zoR8PN^KeLkD>`D@o=Ad)U5AFy6uf7pX2Du3OAG#TXYaxaxH8To}8gp~CU&qIYkv%~#vF-J;Km|hOW=LI5mb~v<@j)im zGYZRA7WG+#Pglo9B>cYwm=?dpV<#Er1v1I+(!@OMu)GBc|mBJuM%wo;M~Q|Nc8X9<77}^UMmN)~Nww05&)) z;p=h2%E`dLaT|St`!italdqEu4Uc}~%Jp)poG%(%&Rm&DMu~tjx^eh97#Y0DnZ0LE zqBT!ufrf!RW1}3MR9MxtM<&$d%5P!#z64c=57nq6=i=BL}`-2_B?Rm8eWdh zKrO^F#!S|aomy4*@K+c}7|&G%6z|fvbwZzpFw1~GwvLYOb4N#O`N9qQRiEeMaY-># zo`GVA9`WXSXv0DX>78y5<1 zjV65}r;DJ|@d?k@Gene6ZXf#a%h>n3;9Ruj(3#L=4o#;1sq9zMFXU`64X}c_*4ugB zkQ->nY2FvoGwP#TUebiRN&WcHKlii2LXlLS4it}AYS`W^dx`Qr_ z*F7{~h^%CpSsF?z`Vbjv=^Ir<_FpA%#u(tKx05d0{3BawQGGrHwo6S(8P1PW?aM<4 zeWJpPD#DdVA?v0&=u|%nF6Px{@fQ0*$=0iEX0U)FZFK08QQETgJ^5F zM|2GwEq=?I6lNvWXr1J=aobdKffaidPJUgfs z&${1jDSo{!dwh)pEHNc}*q1>|R<}Wh3nnJ>c*(QPS4Q_^8~sG0jv!rI8{4soqPko^ z_gUN{g<>d!Kuf*Jamh0h)GgoZ(}}gCq6obE1h>{u*K^kZ-A+bi2Xkku&HlTXk!t6E z+P9bM^T=4By)S9eNBwrh7Pq^2P4*?e!MY6E>JKtAfWz%9PrZC!vZM$lh-e4ZVS=IR z%}Zq#B%$sIOA4sY6NiqH(D&4AEKq>IxZfh9VQ4tgv`GmfQ7k;Al%wt^e(B0Pjch&# z)&Ie6F9YZrWl21#K|g+u-DRxoJ*N3)PGxnN(|~t+W>aqsfFus6!WCcoBW{ZbL}Y!V zLYx6ubLUf{xVMk@fLk0HMTNB4Qk?vJVGKLR*XaUA>TA!`a*FdBv!9zK#|A~-IR%Ad z{Dwi3ETtBGx2B#bY0tJtEP^1Y+OFe9JdZ3dfB_?$O2=;Fi?Kx$hYQ(I|ATPUjV4Jt zltZ=`ia?W6U$wlFTt}#W(`H}qGtG#fBUedcC0Fjs@IQ_hYJv6`qe)EKIjj233MrsUZWIYuJr1psf#;iY`w9{3g)&G^kJWS^=)`$S30&Z^f+;}3UOh)e4Z&rZ9vH+X-<5KHz;R(vuc9xfHvi) zv!HAbrOMbF&QRvjaER=r^o;KF(LEXEgryn9Z~A{i;!j8Z`*PuSWc}JNYzkX{z_biW z=P#o5WqI&0Qkd~>cb@`>OgJgb@QU7TCJ`Hx3_sVgDwInEeUN%4ECQXa&5Mh3&+Ypm zY9jy1@Ou|tMgo6iL+Ga2h=G^clb{p4*FZ$j9amw!lQ1>41n&AflM-_B)Jg+v9_BFk zLJGhA#1Du5{ELkd((k)MZa$o=H+6SEAn%j^7Z-YJECTUW1~jSUFr1#CXb_Dc zz25G+$x|Ng#o@7%`-T8zZ%oE6Rb`K6AEVgyXAopl2CXVRsJ}O=9rjInq_uyTwlo>I@=9Zv)S|bfw-QIDL;Bmm#Ycn z!ALp|WOL(XrfS-gD-7!w%sEoyHN4d0Qih*$%57nteo^?<9$ZRJ$qnF^47tq88{_=} zbo#~Pv~c$eWt8}XV^`9C?x1Gw)AAO#n!=zQW|Uq_M4jXcw-9C5+Eo$s=ra#pGE9M85NHlrY|Vk%rk&>Jdtz%;}`$}IzOAa~||{U8Pn z%`y-X&Ilrcoh%OXU-AKHxq`a%>t9tMEnS6#&(j&cfe!VnKYEi>9&`R#g{EY#_Wes) zu{|>aUr;w&Xr)vR!r1ro;D;WsTYQ%RQVWH^$bmD7bC9RJiYt92nZN+q zdn~CEgHe+x_DIu-Vtd-An?!Fl*@0bA-N?esR?NtDM>+LSf*)ozbc`~rfH#Hi{x1eS z1;Xx!#EHA9HkZb{g#)SpB-qJDvv--O(Yf2y)}oM(BE@(8Z+3;YUT7%66?guqy_ZF} zXM}E3HsLy&(8;XThN&1pQijv#HErvSOC}1Dd7 z*r?4f%yufQ56Nm9IbMcGj}!8(cjwK1mu2xy!?XUhsetugMgkF5qxfrBbBtI7;Iw3p zXaD|NUIJa?=f}=<6+_ZYzc5t}5uRc7Yr`|i0WQDjd5?8apjC^qZ3%B8n8|I{Mmr9{`yup`-Nif!A`xQDEA>v^|7hTdGr~t z5Y4QLq&O1q4$oqOv}u9(RY+nfyG>OhQUlo}e^u7ob48XPRtX(x21L5Ie~g@uHIMRj zTt;nVON4=-!%Or7_NsS2?dif?`xWPZK~T4l*6M)>^{;&O(93lBy9+UdG4>V|u5|L{ ziZE?3+Nv{FbG^dL>g#Wg%5-l=_IMzraA_~PbJ0u9&+!jZ>d-N38Voz#`v>0-d|)3; zdkcQa2*d`DHTMoFo@s{=Z^m$DYfWO$7p+wzek$xvlQqU6)@lY5BB?|IuTbB}4Z?{d zJQO2|Q!b}qLN+7|2Siq91s8Uip~b!1>xn`R}@HQ5m`p3KMegl;~XYJLgf`bwBGa!52QrxoVs| zT6`j|rg^Vu{jcirnv-9mPdC_ZD(iA|_odz3eG_=>VdJ;bFB;@PL$>%eb5V^*Af2M| zSv>nKvWk>grv<(#cI@62K6e~9p)2lL(;=q?F~ZeRKJPVRQ(z~2^7m;a<{7~oB>jS%ZB(5&LLnxU!jwg4MV(>X6+5SQ1-Ev`@eXKZQgDmNUU-C z<@$rC|A%B?rg*NF(TXI{MLv2#;5up_UvnWeU#g+|6BP7##F~P`N>d+Eh(0(`n2cWi z6ESHT;IU|bcyX!F(UxNit59bHV>rv?jfZ+1M3BGlfDXhH#l9)}79!6;jsH6$=&gwP z^Vc>!^I$aX#F|Ux7Ei9H=rtexPOx0c6uqh;h@@4Qn-3KPQM(#jBUji4KAN4BM`u7z zqi$WLC(${u=OxPb=`n4fsLm<&$WTU0JO;AiPW9&z3#`v&h6+68!M))UfBlW+=}`>lE)WFbq7KXl#)$6lKuasY1JpWVy}4wj zYM6x9c>{EIVb05a3?AXGdvoDf8IU3yUNz$=6j~FiWXptFR{F;wSRR|iB04~kG=VuQ z__MZyFtM;~v+q2w37DZmDl9ws1o3R1ItUO4lu!xCxN2;)dIlDP9o3ZdnUosJq&+^} z9gN@=14N}Yb@<}riM7UaDfG1=0)1r-yz5}~n-}Gs|kUt7+y%A%#J>d|K zSEj{MH-sF|ybOv)Fr`UAG*hZfr^NE2o&+($_cP@ig^~M~*E`yyNpX(4QbRgY2~yvF z=A{y_?q6JK1kiHWPeJ&ZQM}s&PXp)yVh}WHfEpkc6@dWo0cPc%G`xsFeI|bf>LW4o zN%_ueb{YUFBz{95CVKD6YHS;iYMU8=qf#ase7Tg%0?&nxBZ>M$=72xYyA=QXwBhfbLY@#UGZL z6k2ClnZJilEJR34EIQ=*Fy>qb5hl=S^N{}>eNJpo`Hr{qHi1;Ex;bkHWryS4hCGQJ zffr|6mppQ4mYi5p&G4Z&%cb}xwmr`kSaV>-ukb&6xFNv=aW?x7djun&*;_Mf4pt?~?kY$A4)Vly{?eLxC;-RF^NIg_g$cn1Q zSktfO#MNH$#ahW;T8Ox;Z5*i`IC`Cng!ep8gnzu=nopOK;UM+|I_;hCKGW6+1w*u%@Sq>9`j-VXmT&ZzrKm;_@ z|1JfS`mTzi0z#v7yVU&D=mC1=1Jz2Y%M)0*Xpk`w&qPR{F*Zj-?t=N34T zy~)74S2#i+^0(Ysclj)K3dpi~HFb3YwhMzMq(u?X4m*!K-KU7RN*9|NR)j}7_PL+) z2mGv|5O!{D`f2adpM(S&dhtBrD^cQulS1SUy9hG~^F;9}9|@c&vwbuRSQ-elci_Y& z_s8|7+{D4Wl5Bhq(vGo2qFmgc+p@o8Q7!VP_q6q!~GoZP#?9eL|Eht10ZQp3W%NXmY zKLm88PX|}S%2^oWKX$*54|={j{&T#XaYj?c6Rx}egIklg0pxvJI-h_j(@+R9s8l@H z&}nZFA8C4PjSgGy=y22C2u_2P3SX=S*}kPIIjR=w>lPDLC<>0Or~-$Sh>56U+#ZG5 z#oo;La}0m?{?g;h*Le6=tp%xLj+F26aHZEDCzDSnY2#~;qL^twFuCmC-NzRitA_hP zm=}1~aeZLr-TnPrLi@=^V@$e=7WjpeZnJ}LUpK%U-vne~OMB@+f5QqA0M`2V*c5j| z@R;tRv_n7hR;s1iYX7mcz{`9?@_*RsC)-bX?Dv9cwVr%(>_X}^jqP-a(yzC3-PLl@ zV87Vb=2hSUn-sU*f6a)CxL@VSkBv60ngKD@q3+i>^q(J!V(sRYRA)vNDF#%+8oz|X ztg#bpyhyb0K2}Pbyg2UkX7Fg?C!HI_NHwVvJmtvz)WOrpU}i0S+!-dEnN0Hj695fj zIr@vLEpSG>)>cPb0{DHl=6_GHGa0LX9q`z07YToZ_|CK`OW+fhe$i{7S4);p%y0kg zV6rrTf&WleleZd@yyk-_5^VW=(ma(HPUCzEdCAdrm{<%oFxlqMPTqYQs;c82HT2=v zn@1Zo>yi$OvT-s*I0CIPMZO5Gyp zj9oXT_B@e{MWeplkN`SolqwXX(tW-k+T=xX*YPeoOFY@bz-lxt+G3JQc0y~HO z@Ur-PY`3+a^z$Yow!ujoO8cVwj4{8;zM3RryOU!pHq^{jStnZlEYxt@CflyYr5~t> z_3shD3hQ79n&u7H`68ghPaK`^&SU7WXAp0Fhj-uy@OeLaY`~grCz)?Fiw~EU+G_EA z3BjPAY|RoNt+0<05M5vBs?mwH)+G{r>Hg{vxJ&l=OkM9prakDbsM(f2t@COd>gc20 z-N3D^jhBVbk~x@^`2KLP1GCB8zU+)L4rHM^DFr{Re3>n9Y z+XCJ*Z`PZNk7pffvkq$-r2l($y!`m!T3(+lybIhMU&9?oRgNcDW_u$TpQC4>@IZ~Y z78l!fUNh^X5mcYGNKx|-=rI5PAr&|!_VW~BrG!J+bRym#BM8PQBVPRIJnna_W{aYH z^M5?@>R75$e_Th&twqh;4!jwrV!Ro+Hv8w_48_mcn7_v$%T`aPC4#?j=Y;t1OHOcv z<4K>~Q_X*KoMHXEtMU9^trE{%sa)f}_(7pp?2tbv|jXGQEyeezq@p|3g z^b1Vk5fY5yC+??nkNR-ui(q-DuQkR|z0a`7y4?jW`hJ6232DH+PzT_>n~iYQ*KCdU z;)r8nYCu+q5A9VbQb0GT6>h>fi5td-pdclVXuy|0t+yYzRa$9UQfp_ZGslV$h6Kq@ zbCeCxpj$wen_vZ;L?}x)B-^JvY(hPo$f2iiAwONAZgGw8wMPJ>rs~x{`q3pet5tij zDio6Xpj%87fBBkp?IYZ}jqz?}s6XyRZO`#X*9K8DU<E+bu-k3}yP93q_FudhrK2&Ia5w65YA`0L+2XU3uS#LbDM z{7PWy&l;Fq74Kwbtcpg+%wt_Pdz=xAdF1cl%uAiq$>N7Qw{6MnA$qfq<2WXaO=ZRW zGf?5$bkxv}X1cA-p*?9ILf< z$~#?;78atJd&5A)J>(d}dnH|jTv28}!|TVn8QxOJu&Q(B%Czqrl}7cBkgRYwQXix@ z7z(BpIXgxCIYR{C?1q?rt9S?R3~P)zGD$cnw@ZI70zCsc)tG+B zu40p`q{zz3zh^rR6!JQs*7HO~oV+8urrX3F>gJsJBMkEYJK3%N{IvbVsJ(mv*Q zW=v3zoj!H`i*DNj6ULvGC1#^3NdZ57RUA!kyLm%DK$bAEZ&QTG$iWtGDb+Z-5~vk} zh`kUrrgIgn4Naw$|Jv-1lFq$vU+~`+D6lH^UpL4Yf?$*}C1pkjg`aIGm8Cq-} zQS7vJ(!B2L+T&qcKgRz((ftgD1%lIDeFhs}250a3jiUn|*224<=V^e_n9GPO7gmOe zTpfQLKD)pm^%39yZE!x;;l^FgQY-+)cx5m*{R>)BV&qokI7n1coET{$hqM)On65{U zFU>d@<6#ooQ87z|QL!s7F<*u`r%Hj(u+W58`7NzHeYzG0fhJE~Qdzc>(4$V~%m#K^ z{M)SNprw4_IGVSk*4vJYN(05^CLZzh}QwFluG0yIp#x4WaEP?-YX8_3FAY0q9UW;gC zn_H>yDdDrOq!;7AL8ZTDR-}%_3O5Fi_8FHVONfNI6_#?c3>01AexA(uN9NrVVkoJQ9hF_ET$rJ#e%%*5JHMt5^a-c2+q0=|^w4jS>+*7R%e#s15! zLFEepH9qb6&L9sO4>VW*{2_?IwN4w4sp=n3VZ;XGg&}l%_bN<#B@*I*=u#h7=}b1n zvz5_^oP=+8!X|O-a#)l{ss| z?Rm<}+4mV)VK^yDwqViPDs(FXkph25_5WuTkW~aq#d?(- zAO7Y~irNj^h+qQyd$-KrAEjUG7F2j;b5z>QW2agOXE%0B76ac>IWWKfqTU3uIf$L@9f=CSG$TTeKa{1*u&y7< zAcjI7?#oYCWB~oYrwHW7ns6?7UO`i2jGF(V)iRaJtoLklmgYqYwXsM$N`GBhnO)us zz%|iDIEQSFHeG)7JIw`lm;aK`nec{2ne&*Vbn^>frWz45@SVqm=9#fiVh!RFaeV+<`f{)K%U z5n@hbuI&=?DBfGZu5h#3|&W zoOUvQtnDH3fJb-AuUwjP7G`U8+C}J)k-0PD5y(m_CQ4r5`(`+TYw-DBiA5ge@pibb zzaV?%Nr1G6CPI&J6|i7JyoOM2MP()^-c%!)zvF?7&=m~1KDt}BT+-=i$Z*nq@c3qD zOHppa98dNM+3-TN7=fO`G?^~mc%Ldy3Y&ScKS_p;q>wT9XEhu_^$aK;SqzH4)#g2Ar~zb9%#~XbozoidEuURg@^t7CogI&cJWmajA*++W$@VD{PR7 zl^(g<#Mp zEO+wq1#F=ZI_RHHs!@Fin3`+h!+niQn>*iYvII59Lc9Y@MI~ClynYk#gN2sLWosL3 zNYu-iQsAv>koc7snNGz9PjtVly4;VLMFnidjrOdgn0d}d#X&6?&oR&9#Mlgvg42gD zSK}5XR=orMLDd#=()us#N-EagJou9;&bp z@E^8x+q0gK!20#yKq41x8G#SBCsMl~`M`FE{P~Z}2DPIx;_X0n?qDDV>;XNS48q)F z10b?Ly*vC1FCfY06)J6c94+f}H;nx(y@}tN!QMUkM}~D5XDtpQKH;jc=EKs2R-JmN z>yh#T!TH0D8zd3ttTBmJjJ4YKp(P2Z51He^MbLhguua8UzsxQ>Ikm4t!hSSoA5)nQ z)x5f?NOQa_m8O*OWO5(^3>U|R$0h_1{yoPDz66}-ZuE4VoAT)W9#^>no~T{Gwb3L5mwgH0$scfvsp(C{DRWR{>`A?H`FkPWwX3V4lNq|J0n(}c=3;ZJSUDkqV2R4iy$BZ*Z(xFe}-_{nV_f z94PnUkuhL@=GM}7Oglgnp>X%t_e9(a@jsRVqles?0VnA|`fY6T+!Mf(S@mig)1~|R zg+hkJsfTkOwr;JK1((>BcUTEH9tFiCzlc}qMKmW5xk)^dfPJ*a0Wt%{7rTzz|4aC- zd>@-Sq8O1lnjy7eXEaQ`mFvFY;|i&J)3R-yFzQIH!zD+oetj|_iOtwduo7Pyja+EY zb3LtFzdO>No8Z*oV?x3v+gRK%K)^S_X4@QvOk|fz@<~qXeM}7Tu;4-zw~imVb{L}B zvX273mQ2%20Rz@gSR$bNzCxSp?>qwT+q8L%^NY=i1_*0?p0qp8dcouULw-Od5ut7m z|Dpj5Gw!f_>DH^ku_>RwHW$Bqa*;vv^eXljA<#XXhoBO2>50Re<$~c+1myPf>Bvn3 z(g)-89BaJ0wOhkR{C{KBShP^m)uKfa8mu1c;D;j4V&!>nz~Fo-Fk*)7E?2?^swGbm1PNwjV>5|B-#Z{#1!r0G!pRZHG0ukuT) zMzv?bKB|;^tJLS9ENORnCaYee#XIrdi3#s1t#C893KbtF(t;w32>r-kWqdm8`>EX% z;U}HQXxH`P@{=9bO;^$Czj-lF6>aUAvV%akBB#bFxVTH04v&KMkErTepZ0kbHm`}& z8eDuM7kJPO|QL8AyW8+}3-q*Z}a0r_p;+b;=@;(M|i)elgVOr{0JOUX9K5 zyv2lgA_QPh=9Wfgq|p%)70x~7r!IGY?jXb&CE!$;-hq7eviV^o^naiHG;2r?J|`+3 z=cPcBjr5+XI`Yk~ep19(WNRr6>L*2LmwC@+HO2`;xl|sFUH=9_6 zw#Cmpanh)T^hp%%(b^_hbJWmEE9}+u%d8`8t28J7$`$195?N=j*^N|iL{%b$rIH&4 zym82hhUQ7%98f7WvxG9&@H*0P*bTeb9pot07Zi7a4}or_dNBFdJzgmbzVTS2iQ)xP z>jJs3L0k2>!?yvjSKX}K$PN$q6$8HZ>9tzb!XjXR;H2pZ&JJ61etFEzpi z@l?HEHJ}c9dMpABCJ!-7s5ye*93u=99^(zSweYm@x;8JI_hZYs2R(2hLHmBA%UeY31BMP|G$e=o~>8UIj*$Ll__{nASz(sls29 z-Om80OS$YM3!kRGL(xC2N9Ey)OFQfMSfO;?-pHWYM01m;w$Cfu)HVh5!lB4#Q#4VM zr7FR!>t2V9h@0*%>UF58)#lnCiM+O^p1lFw6jyFaK`#_mvG7Q}lF}+41N~3sKrFnk zzc+Ku!s`(!x`1w#}-I@v;OkzwB#5?1!dql{U5n?GSq^)VWFJH^X-8y#g ze$opSNw*%RB_d5{UM$-#)l|ajAs#6|2qOrQZ2z5S&&C}r4bMMpP19x7oq-ClmJnen zn`k|(4pA!^puR=5jdtC#z5@Zb$pw$eZa*dTVt5ktQgbXv?ugOJk(`osm!nO`5^tpqCXs?4){kX(s^N@reKb2sVT= zT6=vY+-t??Eq6$TMtcXj+RMI6P=VV3VPq%0jr$k>)mJ#zQ+ejv- z9yOVz?XiTS%*%Nn&b&^p2i^tEX9e{$!`daj`to&Y!5qxFmG-`kJ9V=y)Pz7i-|d1( zkXNde*K##scyRPUDIVk_%XZ+YCU;SIGRPr$BgZP(f+VrmkN1p zcBv=P10-gNA8LMa#$JY-&~@<2JFxJI9s-4;?SS%P%W#Hg9wGi{TVHh*Mk!nkt>g%E zRCVgh8_C*P{B`A2Z}W za_r-5)`^05{m=0YFop}?zhbqzhlbiK>dS((9G2eeOuhZe(vJ!l`-}NI&wt^TK;@e5 z$_t@QmFevJ?iv_y{El6>YcGhwWOqaQelUDYfq8n;%$lLh8rZLQ<4S4bY4BaghITwO zBWfPam>5|ajB`@_v?7dWK(5bP^R&g)q|@raE<@qBnSoI4rd*Svy=ahe{Ywx=LdrYw z_ZOb8OtQQ3Op;|pS05|V8Ok~1YI*-`3L|uq2O|6Ry>X>Wz${UZga7G|=6{a#zFxt4 zIBG%eIEs0L+Xp%77=!b2MEfKLq3Uho_@4Wz@e+8qdtI)Exiy4?O`1YWFFmEs{XH)3 zPhvO6fJ*1D_Cozfb&H=h{fs?XR`$Z&mM&WEgez3B>DP{l5j<8!1w8#le(V4Ig}K4e z9g51CD#+=LopF4%Ue<9?>LNJ%`#eu>cN0*4&)2ekvlK#K{kUl4T1QjW2R{HS-4fmm z2FOtq`EVHW9)LDbk0_ha1VUMkMMTZ3xX7yK@vDnnPToswIZkgoQ@6gg43GbvN(;zY z;to%M#Pi>%MD2g^P#=pNEUgkVgl%Q=G*Q1&a?p_(bGt`RP`sHe|4MZ{ttc2{9%#jJ zHIy{h^8Uh8>@`W@{ZHK02T_!y2J&*bj}!wd5L0FzM&+z`E`W76G1dmJS9pIu3q?Ru z+)zS3-}K5QBKgo)6z`MDHS@e8on5NbR`uCDCno~pvJrFE-RFR5or-|X9BilZy}t4v zS-Rkk?CUD1t3B7guB2Hodpe^-Xv$O-I7(;traJwEO}^+2i!(olRFyoQnk?sLFPG(V zd+EEs_uezSgvXLJqkWxg_!XXZ?j3>3pgOVq1JDe2z$Iz&1o&4Y2nF<^HZ2J#1P6ur-sQ zn-b_5%*yVgJSwauMxvtq+x^qJEWoPyQlB)G4uLfaHUt*d5YawzCn{GadR_Er+)Nx@ z_VWbXgzKdb1P0oUQMe&0qRGkTrh4o@q=f(Rn$P8~VEH?CAc~-2&NJ{29f)&OpV#e* zA`|A?_3f+OdcL+#gq^YDMbzwB$@}lA$&^*{`0QMaI+<*L7`Y{hyFmF{v*bV_aS0k^ zBy_d(I~$sPu?9w0abcZXARuDx$N>)!hps=@fi+ehzD4_!)iu$p<9 zS_i+!%}7d4HmHaT;ia2!L7V z+WR%t$|LJtZIumYnpPLV%ilcnlB!S8|!wBLCtIaJ@~{$yPB_f%Lie>zjyqO4AFT?@os7&4dbl?53$b(g z+gQn#Ce2R##nFYi`Fl>qOE=Z@YqDfq>a(j<;jM+VqSERe#b+7(#%uUz8yewnvk}G*BNlUHAlvJgY1Lugq z%t~C5IbO}+YRp(XqULatZ3s@usoXM%lKV^vW(sgXwr54ikbLr?P)+;KOp)!*zHt}K zsl{89EH2JGYVFPZNw|9oV_dH@rK|IS+B{^UZd8)MtJ|mbA z1YuF^`ppFjh>Nc`QBW3eS%|~@4=jO6vqg(Q3T7z=hx@9w{;`<2jJsfDC=`eWZC@>o zG2$P$U#LCiAb;F9v;C77FY~z}rZq2IIU7I`Sl#Ieiw6UNa6Yeqi$Hurgdj>Ovv`s| zz#nX`Lzq%|Os{wS30D<~$eH1JlrR;~(D;MPj}!03A-P>*a>EH$X1oNUTMubkob}4_G3zKShpmT%k^kaX8Yvf_fH8*W=(Lzu9T5>KE3!o>6pF zP-{Wbf&D(d;mcF59$E$BslYkQk`rHIMK+9OLi|ofpOKj2h#@jm zU1vpE-xoZS1vF83mD-%sZ0&}$A-ixZ&MNvdh63Bx;A|yomnVB(Xi+@0A)c@_Bg{G3 z=43hQBuD2N;pU8F{zLfWU|%YIcg#k__q8c&Iu>Jk7HDztqvVj8<^*!CwU=j-gl;H% zn#2Dd`MTPQ5kG>0VWXga#FQJoM+iGZs%0cfR%k~m$6#TzM&iMM!3(Ktp_CQU5kEz8 zPP$OAAfEZfp(mxSM0;bN!_{01GEN2#=j0fqPPL&sTy`pi9WCgTFQoZq7>Iw+d;>)& z@p5!#Emg1(ZVqRsx>)`0dv5ZY)>G<$P=7~Oc;e}0Eq`_DYNjq9*8zQ);OzIa4ybmc0~%BuY7cS zN<@Ahe{gih+&&4fWYVO}I^%$Zg}nk|6Wx#m=4GXN--m0)^RxkdYE$8(mv-Ot;0mJK z5l&yH$kOFWueat&IllYLb>}z6lpRDfO3c53R4;+O&m`Z!pSszg9+V!QLYbN1hZ52h0m3ZgS)wI(TXYzm(xmjgu*NNwKZZJM0XlU8p zWHI*^I)^du5Kf`|c z{pZ|z&;17ubPb;9mSSp~T|UMFMr-diB!=m>op+vw(Aj(w?BI?NUkkg}#~IM^{Hd=f zbprEYkBdxlQ&)Dx;(>Xmqbtl-& z4K5`SV(gcus6rs60-RgvtAAT!+c4T_@KlAj`mrk+0GX4==_S$S4EXV@E5eR$XUXwJ zll=v7JI&g2Cv!xIa6~6FAj$X-A0-g45d9{ShK+WyboegD@Gte=*lN#JH~*uxeC|G@ zq_-r!=8kVqA}65M|CE`BVEi3iK+XcTGSehaIScv9^?iT;=so)blnxQv1X+u0chvE>{cGr)s>~tT}xKF>gIl$tpA{p zh5Qa~&nu0xHv<8Vr{{^anrEJ55V~!>h)eZGzXknUd-{ecsz$e8V3P=C+zFuKH(#Z_ zAww=y*udhgeFQ0z@Ztjqt2UI>eKPOXn#{^8b0F4ER4}k%= zKJq>PYq@0$o5+Q=k%QbS`NH`#;;5gIqf{|e$5m7b;!i_ehSphB=&Gfawug} zm?1Y&O6))kYO-GuN)~00h>NIgOkR%9w%j^CFJiT=ae-st-6Vgzm3>1=7*MRf92_-0 zZ(=p3xAY1=FEJ?YetA7t=(~Ic@8RIWcHSx5QM7aTd2p=?eJFwP%faTR@7J7SkY3glHB=KTmBcceBecbl z>Cn9TE|}ZPg2C%b^SLpFPH~G(M7U5T2fEUt$^r+0@34;qrr=qX{=sD#H{4$Dz6`hH z(%R!7HMy>=m(E;I6u=)%V()&YY86@)ge5Cz!Mw3;1+Vhq-xqqBXFy3zgo1-QWoAYC zrx)s=_cdY@A+P=sQEIIT_>?Pip##bLF0kG|7O}U=!&(Iwc8AzQ0jNf5O2ZxfA8G~wC2h!kRhB8U~#+KO68|exfiX3pR-S@PFJX^ z;DFOtQ%vrDJYW-ErDy?Mi8{!coR$jLmrheI+gIox6=fW33ZUdD#jz^E!Rw zl18K~P-$0Kaxa_8+cQa_B?5pUv;G~1_o5k@)=kHo8+V3>pDhoLcHt4cW!_EmteAh@ zqC7*ajk>6eac&Vts4!lPLlGfMfr?)1Va0F~{#@mmnU$HrCq<(;w4ZJ)mLESUM8uf2 zYB~&m@G?HhA*oDsb;QT{S>&aHH4AdEkZ@UL>}uj80}N__b$()BhI4J*!NaD0vO`GQ zEqCcdJA1gfQ)az@xX??Uz*Ockg=`OZjiVfPo4QI;6pQzJy$t8GIkY$Dq^_gDO=Zo` zS9jIOI9wGaU>Gof6rP^)Nv|s?tb&xCQ<>^f*=yle?W+}j~>#&0O4HLe`E zOCq$Gi zO0ATI>jDvlLbzyfto!aRIZ)G40|lx(u&MKzs@;SAB5e3p?c_Dg-UBgao|cuPo<72c z(FbqgtV!gQbS^0 zJF!XI`I0yhZ%;lMtfpO;tBj>0;r<(sS|LSI$UJ%5EWkp{0S3f8C!R}_ZhT?c#BKUm7Pn?CF&sh(fBNf-Uv}L{!W2p5i5B$WgLtCIpo=W<}nizMAVkJjKpF% zUs>Xb?wKyyXt@9P+2)V+A5DuSS^X3N-3nJLj}J#=g-lic;<*jL?yZKldb8eCksI|l zPa!nXpaLUh7N}F-&T>I*l`Mp8kovJ4n6)iBL_cJ0oqqug|@VvPer9NY;BpI0w> z)=*F~ri(#Bc>feyQ+sxsq*hsKY&e~~W-N!(&_?m0Vz?%|Z7k8uM>0?8HQNK(w;as1%i#1{kjK(x(|m&`g`$%mH8eScB9Y0}GXz zN~w^iCtI1Xomw}}kl`_(*V(gI#7FB~o;V>HKxn~uFZxBU@rjv6nO!tlI_34C8J5E* zrI+FsyLkHq@}hU)<=3JXp#v;_ni%kA|DLR*spJcWEC+D$sMjMQBAs^n{YjPa+$xLt z+i0gWUCZwexnJJTjeOdbZld4s#pLPVOPR2OqDXQO8F zj`xC9qBJzA>D&Jpxv<1%HyfW5Q{Ddahu0-VsA zTi?AS{R;~2NRFwo1h(^(wC1-MR@;qXWU(<{25WBL8F!36izQF~3#Qbv8mk&8MLc&Y zcIu-V?%X{M-$}V=MQ(l0#!^WNG-J^fwMbJ zJ|&Ewv-u-;T~Au`1u9e4q-kd&Dl812^mJI`s4WC2vvf7AIE;!frF9iauy=;! zkzMz|Z$e5iW1&g{`X=o6#8eSPk^>a1T*-Ayk?rk$>nYPQ1hL@?0i^SNbltLTZ|Ggt zT89Q~OL~F^$|fvCGujc$)d3U)ETj|s^jo=lkuSLf7(qSn+pM}jiz*$tC!!1`Y9=<_z#H=yL!Lw z$gG{~UU<`^6?kucmY@t@iO7%!b{=u6D^Q6s(hRn679jP<%TITAc^CduqH@7vz8dk# zeGxZw7%KIIeeSO&n$_`=q=b6d9Sq;ayjN=}bOa7s?Y++tO}v`UpmOLj5o|#~Z?HrR z1Y@>)&5{6X%WNcRZtT=to5zFm5{?oZX#wiQ{z&l33?7Z$ER)1jAB@7qq$TnRVZ${i zaeuW4&=?U6JE2fytingelIffa^2hq5bx54dC1NT+l49qeTXzF#KA|KEpt@p_LmI6M zt`KHfeDtI&mu-nDhv!FCUND(48)86AIDpm8KJ>*dU-5)fcQ~H|TN^D65Bh2MQ+m#g zxUpEk{94ZPR}~POfR5E}EA?j2>c;DHJ=kv{g}GcmYH54a_kT+vYXLkQuxegDJ*Vwo z#6u|*_2RQh1#0fu?K!+hDKuv#eoXL&RfU5OoUFtEiL!D3no36(57RI1lY0Y_0%K4g z=YQ*f0Usfpe1WRUB}LxqKTNz(tzraODnUVQ`VAVt_ zI=P&d@GnVlJV{cAkSp{$3s$^#grgn|U$RSdmXknEayG{3=V&Ch*W zbXv75C(eruZWKS)0}@(jmAF0&YRwV2dXz)qSB z_h&!5&?H0?NF4kY{S~nR9*C*J6DfUFIH{%kYl_v|yalfiZqge9+REG_oztcVKSvS( zQHF!fnj$C0^_F zB?@B@k24&t=pe*VD%g2$WsUa3NK1Qrn0S$2>&`J_9J>@t>leDAyp&H;VHW?1y>!|V z1W>?mRviKJI7hlqub41rHL*1|D5pp2jaq;2N93OMEXIh{>hU zkFWwJ*ZN+0kczQDP|P&SFcgA}k?b{J_`{~#hpx8RD(2g<(u(1t;3{Z{sq||y1NDE< zi3ZM~#S9}@n?O^|^ko)Hy#=PvF=?r5%#)PbLi`=PB_QrhbRAKM$&g`ivTu2zhAL$roQ zjk3n0-MB^-TPdygnyFP6)lK2I7b9H58{y?u^mYNNzt1B!^bg~0twsjK=Xg{Gz20r- zO*9YaW|vDD19C?Dmgr1B=g1IjAn7`Tdv`d+eflT@>!p7Bwo8hL?SC(WOH{9!RWb3<7UgrL;mBJ`*zl%IDk1Gyn5TG^qPNX)iVh%~SJE%|AEkKxT2&>^Mxra_ z02W6f_z4o9Br=a)Mv zyHgCs0OP}))T4XQ;xJie1jkLAWA%IwlM8)(W1Xg5WNK{~^{0 zft{5K`EEY*oS`KyQ$Eb1Ux1VHNvz_Hfv3jYiYknp19l^40kRoZ_rLabvUa#KD!B3!Qfrw^;SCoMI^Am}%Ziv7OI z^woOagQ4%0ZvO7zK%PtXv5x5l_!Zo&dLT0=%qsW2(OXh74Djfi=>|S=(f}mGo)D$k z7tMS__HVX(cESCTLl>4urW(e0WgmToq+zOMErO!+rFXN^RHld}^%03Bjc4#~0-tATt6BT_w~SjR~ZU$f*& zo3}&6R)%``GhO6rsA*|B4xTgP*~ZLRc2H!CdJWS2n4Fy`_=Pn&rmQkm^IWlw+Nr4A;oQiaRLxMDDs2dlZsAeJ)IeU(|G<%|U3=;OqJ#gVvK4^?G2 zwJ@f!Mh>&I*F*2ln8ZiR_zlg+sJz;;72$$(5NdA6biZB~AmC>ZhCdtETODsM6xmqu zV!I91ZFf*wgHZjG|F9FT{vC9b1my4iN8-S3Ykjfe=P-|Z2giKFj|6rfwPSC<1`}G~ zw&P%0llz_~6djDZ=8p-)<&@U1$!`A-w--zhP#7yH?s5sFNWO4!m2d}iU2KbYWDz#E zo&F~K1e%LL6O*qKDP;q~{VGd|E}mDiEnCFb5m5;6s|(Pz8jA#s*}ELuCjG4ys9m*r zKr(UZ@?*B1q#^~X*SDM&qbCKrT_U6)UIT3Q*HVW4<(ytb2~zZI(@+!OuqV;fsMesLlC0#^iUAu5~LiH z=XJ&3c&dZ2ti&^`&E^be_@BI8OJ3eiYn|-uBWN`w7pB2vY_mJfHlZ|pnJn#C7NDA7 zvV!X0AaXh~=Y|UFEG7-y#{G9KRdag{r`H21RyuG)YI(}0_|}gra6~j=K9>{h3n|hm zLEj4Srg4~W(|ScIjonXDn)`Rs?hXM(vtf&R&bBdxb@x-agEAuix^;$5+W7wC{MNwA z{Aqq*OT-P{(orXMS!L#;q~GhmW`74pX1M<=<^iabO>>;E`_H6`Nvx;HBvfJ@A~9~-cb7iQ zxe1Wj;V^Hxg&f1AionTL!Hx!^E1 z{mq7hur)GXRCTc16Ah%^m;E-3pk4@BHLEV-dKwyveq2Iv#qfJ7Z$Ps^{nDf#MsAWE35zlFTv@m4OK)3#_ZDw`s$K{$Yb@G!6+p7D9B@ z$HzzF^nz**l+9Kr^z{CAAw43fd2jTV1Ez`=McF)UPgu3MT$-L6Ybu4GWkDr87kn7% zFrOR4;o|CivlyWwbenzuE^GfY!!^pD|6SjRPnRSI+lT@_y@9_cTn~Ue8kc@Kux{!j zsuo@Vx^>$){(OVtsAn@Z0|v`#5WF#gy&}mR-7We47^My9WV$yxtzqh)V3H|zz#MS% zACI}Gy*f9Por!RiSM4OiIeF!_s_OIl@qB!VE^r)nkDFHPtR%QS0iF|qlVc$dEgsH{ z*geBFmFV{R4UL62RkTCoSf$dMe$jF)CpjL9p-hm!l7~6blYp24tF4I&v=5fA~*-Xm>}z;g~^2 zixh~f%aC1;yQ^^%w38FLr;EK5&N4nFkfIS0n2J%C$Z_z*mR}O0`I$AmZ<(5}kM20g zmxOhszCATxs}Gg#*Y&Yj{nVP8o{*T2@|a0POJyxKNd#6cy@7%xWqqx4x}>_5W0eTM zPr=P5>qcY}Qy8ryym@WLuhvwbXAKlX7Gc2k<*_o{&Z_Q22mbeOaWO??Iqf9n50m@V zsw3c37)32Ezo2mG@g@vzjHw~4!Es0$m~;*HnN0@clalq0Cv(~?*ttv~gk37md7Rt;BA&Lt zz3py}F;L%DPx4B7nD*!%^YfhhBL_tOYyZ#zHSJYg&htAZ#lzY#rzwAo-WIm@n|qu- zJ%pC2>yAY++1mrOucaFU+KES<{qP)?_Wp5W>qr6vC^*b_{wxq^K{V(gfS+48!Di4h zUW8=IO-h0c1)#AG8I|ANz-D|ZNuYgC7iH;q*7Fk^H&)r5?V!h$|8q@ROQIRz&C02h zgWTPG6Ax$p)din=TXKenCs1KRkvFjyoJ-0uVt0`@Fc_{Wd@>*iaoaSnCt(RvtbA~7 zZv9Cq8KTPjWnlo$LbUj@8Z#pu%}}H@M>I`+ln)cM{-dS78f9*A+517SPjwTpnk&&) z;V0+~8<#p5hzCiFHV1PTe|)Z)QH37^@j^~tVDXaziDtf#6dYZ`ptSn?qeU*)glZWDWM`)Pqa; z9RMxyO7#7=9jLgql&ELI$_yW{fp zN!0~sD71TJa&8*xXp53?T^0NfQ2?rX-^kvE`wtZT9&Ez2u@zO#xlx>>LRhr_lB=i2 z)GM6YhD&`Ojr^tZ&Q@L4nOUB@w4$mK<&POwh+gn>dNE^}28>atDvu0M{NUBj)pZeP zlCmfD(*>Ie-N5NI&)eCgxP4Cpj-d*6_H~R10xLQ1?+S#0WZQU1@+@sigWQMQbl)T(g+${wy*la~P=D8Zm4%c;aBG5#pw_ zosRvo6qLM4mFuQA@Qm3i>>ee*Sjn=By%0FXn?7|iWm|%dCh`e!^^@GsomF{4HG&7p zZ&@>L1=lVrV>Di8@(-BGV@VEATDXd$YBhYY0ZMNFSYVE4=(iH#ruO^OUM)aP`8>aZ zgmDHnYAI^D{DM_i1hziwGqs$MfUe11#=uFm>y!&U@1N%eQSI>h2r~G*kZJ4KnsS7K zc2RIJ*CNUd6$Ga6e(Ls?>EEZE>nN$Syx-`@C-1|bCbRB0*haQcJ2oEw|HlLplBgGyiM z!r)>cU>~RJBcu~7Thd|o#G-!kZ}!#krT^o{qnGWJ_KDe``o;cZ6N$h|`uRZ>nBIye zEadOc-0fK0{w~1}bwrcZgZiJHS@?MHSf!cpdO7*0CIvZXKC}0ie>~K8PyduzfLG@1 zovTkg@fh+dh^o>qeZL(e;}qWwetmL{({n~FhGlNJ^QOutRiLHP=M{4KTd6L&|9q=G z1G6k->eTs~=$>MJy(p|>jCJQufSMVb!kV*>%ENYl*}R;XZz#kQNQec{7ofn4>* zr-SR%>$EjzqhIZ{ql3lgjn*5q)6uXkI(yFr8cV5D-Eer84LM3b!n3H?Ykj}+LEK0G z;0b88vvYE!?-RDA9~#}+Jj^SvV0WscfJgki`gftz=0HBL{u`9Av!0xI8$YYU?7pJc zy3zxQl0X?a9r@w*%$IKFacxU$UfeM)duVDf4z3d3pmm!+KB?vV02?l9Z%)4OR$-fC zJx(#g@Sw_8o~k=u40dxA(f=XJ*%Rb ze%t9IA*Lb-$tvUL%`)f+R26KUG6a``7GGp5kIhZTZTdg1ZEhvqr?*Y&juQq znRWTf%$-tZ)VOB#AEHSY&nBT>h&*js5-pV?B4smg1lts2G1opQb(H_LL+9_ged-1u^Va0RCJSg< zbA?!NB~JWJPu2?U|?O% zVw98R>0(zeKvdXqT)Y}0Q(mXo#c5%`$@;VK#}HfD*bZex{oQ&8v<1|A3$cbEdw&;#zn5!I9#nVvnqt$S40q3Uu>5x)Vh`E`Eylc+Q+32aki! zm4_}}Vkx`D)YvmNtLJO~6mt;x`-Tm2HdEpaRQ)TzciN88%I17-icCyOkkWvN1}V_P zW8o*|%rG&WUfei=6^QxdtcX30X4+X&u5*uJ;9zRaQ~wq{W^7z>QP^C4<=Tn&q2*nB zo6f>q8!bpH;_~f|t+<9R7>z^`8)4BZ^A?kMs))iO95e-;n*Wa;WNX=#AE+AdI{vfk z+mGXuS46j*cNkfb)XsjwDhuy)hvW*SO$-PmBC$a#YdP^7$w*OpKBez&4CuN$<1+d}eg{EkJL0X0)l zwHARUnxE1p9m%Vasfm6?azd#e;H^g*zz5 zUWH|dHn6jgzyPpQO>sJyZAMQwR%mMU9W2aGX${pLoA^RT>=D~jC5*gQy+&UZ;JWEU zLt$aV3YAzQ@rgml&!uiB{}we9g|PW|?-WD^!qa75iO*fVf!MWAWwLFsoZIE%zVQ;U zREq130UU{GF9H?s@3p{=o!gJI$pS2I@D7VZ@^wia{#yC;8C~UOeC$L&iZrXCTCMvm-$i(zkY&^B z86|#P?DS>5OVVR$&sF=Qwh-WW40eOXsDCM>>1QBNohkr5xQcyI6e61UP>M8Hztaa_ zlzI#PQYMj$ZJv(0mZe9Q(62RN__@O@=|J=X<=HRCo5Bu|d18`RgJ^hthPO*5Rl<;I zMY;xeflaWyZ%~u6+piC2l~;8n-QmZxBUs%(_m&@6#TFM-^uJMa66ZYVY^NU^V8bnP z_+u0thv18jfgwRVNGx$SHs};sQfe|D-f7is>)b-OZ7xMNti*K?-iMEY4FPvHKfIxj zDM|6mtGeTDeZsqW;Wpb9RJ6iYCojVet1s9CJQWhkp1u7HPiE zFtnP>gI4!P?;odcCt0U-b&Szm2vYY|cV~W^9}*8)oNUm?uYXMJOeZFjW^Kc(B&Q=; zqysy_kI;OLqD0Sl!QVMRJTv-O>NEV!(9C;DC|4J zgJW2q0Ay*8tFOY86H>0wK`huV*oBJ{_d80JiL>auh74DfIpw;Wz(H?^@?;MbKO z`3rA%BI{*vBj;?PlUQ*qjflVbJ-MQvX)h4#Jqrs#w=Won_+74Z2r9=En@*6Hd*6Yv ze13H|dinmxv7I~o+)>frsae*KB$w6DhSZr3(Cyrx9Mu5G;tK#PUl5U=pJ1wy4AAYz z?ho;ynx%-0M`>7v`m~AkEf2D*#{2U&6^PLCM-ml> zzHbTx5l#4Y!Xn=`UzQ^eF~vnaF&ND6W;Z+0}3lOmxPPx>&+MIFC*_v6k)NhYpRb~B!44MM&{}`?* z*b@tviZu3WmOmGO_{}HLJeCL*b**(^%ZotH3*uj8t&@0ZJR*7z`er~3vIqt*^Lkmz zEw_V+>3^Bc z-`xNzPlg4P@jV(Z409G6!ondhgj;hu~CyWXE|F2 zC~@UWmx7kpg*WK%?4*_qgLL}lU8gSJf_HORD1P1Y7lp<$8t>N^J4zaR(AP-hv*#jB zi0}E7=v-@E`VMG+j_Kq@hbHnOItB}(kl2wRfb>dH)VXdkw7%;(IAz!sJM^|NoQTmcX0P!j>Z zh=FwB;1tO%Uc;kyzp2#mP+;PMu0{&Y4jf}P>3K->+*W*Y%hFDEF!(Sp1aL+u1Fxb! zLVY(Rs&JO?U%`L48>~aiHKHtUC>15EV2Ot_&STId(?Jx#PMc6=fSuL!@pX)9NldI5mk`LVz&iXa*@L2K(o+P&I+8e3ng?A;ygcLydeos(g;mh1U)_AE5<+|% z*lomPgF)cIsd*oJ3GJ86M63{+<{A;MncyyFA>GTUNwL&*~`X2Ps6OC*lwyI^-+a;i8)`N7u@0JPU0`WE><(l~9#n z-DLIODthT6tC+%OZXMlzaNvzZD5BhdyXU`hs=2;MrC2K)j+vDw1gY3HtGB>mOXlWYVgtTD zivwwu=ohN5Q}oRm`=V+)7g+bkzM^VfDVlS(Vrl~y;+vw!_uQD-!*~_}q7~tO&^#u| zsytj02cI1C)|U!r@(<@>ORX+T#QQ4IHn2ZB@*FX&B#AqJ6sQka+H6Ogx|JII&+R84d-`M70rNxbq>jH{NpE9 z;WbEA-u6~wlCFW^G*#FrB*J6ycOsJ@ZdHuejoI`AlltNj&7tF=lB+&1>;!SEfZ5=b z9quS`C*wmeokl#*i(IZsSRQtUv5{QSTE#BiMJ+`sjjjm60{}`d(XM2+VqHLP@9;!V zUJ(}M4CU3KqaTmMdWJK+-DZ!@{d?RY<~bMg04{romP|-7Q;t~+edq_M<9Bi*JdnI7 zY=r?XFnZ_ksRh1wg7wzMZjBq|$X$FK4{sc-%)t5Me_tiglN!! ztd9QVs_m)phnY`ZsFhYcO!zZ9i9-G>74noiXv|qp_b(qgS$g5(jG){B6Ztj+FN;Qzd4RhW18Y%x~Z1@zaC<7yB zPB?ciSLdD;u)v-s*H=+J2ZSfoBWtELZ&qUP((MvUm!WQ76c6Sjc2R{2_ z9G#pPBfZp+I0x&&uuxQdUc>(#)goTPYQQJCTrGgz!t(KAh)VI?zopa;iG(#^D=MS7 z?xa4R5v^(<-b&1f)T!#!+<{jqDRZm@a%ZPk28MNT+r*ym5`;wne%W3Qwb0H(L5bI5 zqk7Z+a@xYg?#;EZ;m*vVN%N9bO@5AB`O$<`_ogzO00h1TCl;dB@1T+!eP=N?7GChK zz|^Io$a|FBh#)Aqj={V5N@>uc=AUbkR+7COpk_5z(}88Ck?(W(P7Y!Nnpk8{N?I8- zj~9VB80Hmd&EfV{79B&&9?QiiPA{DII+Vx=n2R+jv+DJe)#|D-s;j2% z@%`1X(Y@BnV{#I_#kIa*hG`bNP@;pLDd$iLK28B|mCb%BP9Y&h^FkasP0Em((Q2;} zsm-xVdR_jLryJ2%5?8}VHjp0LAP^`OB_f0>Oodbt0vCw!W`R<}+x?gTe0oP8UMBUp ztWkLp=V>$!!!Zc=F2H4`kouMw`uV-46_LU{JNT%w>hhU>ZhRhc*urD|*;Z(SCGDw4 zno&Xl8m0P(Qa@5z4x=m2*&hEhk!Ud1&4_%RM+I%3s2L>Jh?4kUrc7Y}II|*&JOsO6 zBdvell1^(Edg57OrC*8qpR=-@n(sWsUALZicPi5JljkmPSt~w{}AM6|6m^`x@ z6|A7^xhqZ@DafLlNxZC`NY%u_Ah3pCWKjBZQo(uR8>wt(xuZOS!fHOqttg4;1%X{C zElgD+WQF)W6$YZf*?E-Vd!b9TP{_&}9;m3LdB#V=c~KVg2ST_^6HFjRJ7sB%hB+Y# z@b=OJ6Ms9tuFBk5#^6rqa<%1djhpM0Uvd;5w9@>$z0F5R)@gpZ4M@9_>RPuVqbjV9 zJqFSFHSio1k5*KG_)@I&)JFI5yqqtTKxKlqEPqm3BA7K=T^`lfT7*>LEUZ;!gY@xY z3!bv3`6nn1sr*)p%@Md$L5;rD>%CC@Th}E~x<@5E_PKwZwWpYY@FNj3*HwX4$mPtT zuJ2Q;<-pW(_y9kA(+qetl?biZD+HLZ$PUv#I9wm^%eVm_uQzWXONf^0ZyUHHi?Ds> zQX4tPDS)a^rH*>&J(1_0my3PSJT+G>5Dec@ciS(L4@Kl}S*T&Q$NwJP3M}`UAi>X4 zDO)SsT`X1#((Ws2f7yA@7FA=ayh=?N&8g|I$lJorO8)wX9$7;09FboPAa;ugN?zP_ zD8p}JtN05n1OTo*NO@*}_}neaBAk!%TvcD@NZ&}9={0KCPf~@fWmANFmL=2*^$`9x zTdkE6<7i_;|CMgW3?5krw1^kO;&Q(YuHi(LMA0x zJN*Q9SB9Z)wbPG2xhXSy!=@f{c^lyMz*L+JE(MdpaE{>Z1fJ=aMrG=GzM&3{!PO4( zvuyh_L8m@Q06fO3o4u@%}m`#1UG;yj+XsHyw z;qxgGpM!$DCq)4NyAFFy5gsQwOxVRZJ#| zHV-(0qve0_KFTNnA{tJQEn{?La*|na5&;;pyre^*KUn%|s)6K5$0*IidSM7d`)PaW zM@%=_eRBxZpaGpHDRpsVbZ8>}{KMj#=jG%qAfMfd1a}g^IB?zmxKrr0!nC$q$C)6p~8YwvHFJ zL@DutpBC;ujoB{Y*knU9lx3}Yqm}v%V22(47V2Pvxi*eP$BCvdW0d>wX1du)qnhVF zHWC-o+wyMy#o_e4;o(jlzoFcU5_jzW){e)=X@=+(Ofp*SHU`A2%o5_OR>e&uEu(xm zv5{MK#`9-uY$Vw3FTRisf;ho`Yj=S>@y;G{mV@u>Iwv+3qfCbaa$Ss7F;}vBD|;Iv zY;Z}pJRP-Kli# z+jv3FUxR$6BOIRi45Oi0uG}&A6Ms;tL@s`;lnbu7Y2p$fp@>;PU$A>3Nbg=O{zSq2 z-HP!MK`Kusu+c}R@S^ka%sYcR9oh$9+GDamzIvAEeqywzH3@^*p+$}8Q6W&fj(A`4 zbH~Bd`7RVFodlP;u$eB z#l?_nT45ZPU9P(W{2RWfglsrnNMF4KT0SWl1gT=w{x#(-&H&!#vv;>XTNLti-DZ`kM#4G z#BRE$cbI}*Pe9pqFk4FGO|skmVxqt6aFg0i$HmE>z43%0UwlPh?eDT=t!W>C*TjPx zx9Z~;X0)Y-?!}6jPACx1~_pF9{ogt7obkaKy>nCnHL zDqLFY=)!Np_Y)OaFFlVvQaM5V($h{Fa6@n$m_h;=+(=k3)+VZ0CIUI9@b8m=k^`J? z7RD#Wn|P!U1CRElmB%EFXT;OLeu3r4X&4$hmz4_WN{@SC47TQXpyjJO^m0@XiQ}K8 zrzyq~wF{l$njf6FR((+C$#b^~x{a^RjiI0u%vR-8=b7{#qB|$F=E2hvlXpCdk~f0J zetp$KPl|XwIcXHY5k*4TbdYhigLX~=YQu_Tk_jqn70@YZdlm|za>?H=kiKA5JQDRf zy3xscp}(QXj+UvkW1RUioMVt6H_Cit*6h#cS`kEIZ}v6}Le;;<6>Fpu4-+v=2#b0r zf0<4w2IKe zSq(htkktR*XbheK$%5ua*xxbnILsYO!CNYWQ-l)T`d@}jhx&!s9YHX99*|Jw@L9p> z_k&N?paKBBRQ%Up)07~yX8AhQe8L=J*{DC3$ho+@Sd^zK!f5+%bn63UupPoO?THWU zloF9z`)oDU(m>dhPBx!+uyiDu~6KKgy2xLP~1}7p%g7GuEpKmgBFJ%!L3l-DQ?BBcyWi~Z=RmL z_u2n*y`S@iT-^6$&8**=kpzsad%h_Xb0?&QMMW64#5-S+$bKX6xTVJPF9?K3(ByHx zRt@C$4ykxA6}xnb{;UqLBOUJOvsbkHJaBc&vuB!T4{V)F&Luvig;`bLqqs}fu=O7u zWBCXvS4yrMbD^<^$^bxXt|uyaqd7ghWkyM1D2JTH=f}-=5?MrvwS{Kgq=g%S?)W~c zTg!1OWyko4J&M+{jQ*JIxAGN#-l$RW_5c4j|3Os!Co-kVaEKi~Y{lI!InVEfIPx!| zK@T68iM&~w%60Y}os%eem&4SL_b3{}iYP5aSFGRrUsX5d*J?E_B@mTt;$0Ee%tl%f z8o6TF_AicJ1I-`3&h+h_i=}zZ$z|(i0JVyh@TcD*>%}3JgH^G+Z&$zofkLIg4`{QR z)4(Qwi+Yg(Dk*j2Cz(%bc+3v~P(E>_oy_yCuYQfui;FAWG`-j4e$!s)fHCKd6Jxyw z9fu|WhEFW5Q< zbK~ql0af*bj`2w!Q|93JBcQz3ja*1(YBa~K8s zoh{?W=%P|LcfusAJGnw$4YW08Mi}RA1${5?V7Kzy*9kK9s#3m^fQuk zbag03xot zckE2zyB~<^N?Bpmo-1i_FXuDWitUsItM7-_gnnCDyCnsI%dE|Tx^ncN2mxx< zr1@f@zlXUlDXv*Sf%Q{roYA5}kPmbDugI9;yMx=ys3}yz*Nu058}TqN?RPD>bbYZA za@uFazcnzl148Cho#?~GwJ@YVW*UWRMYwyAvVv9INb+7*d+LU_ntd*d(A+C{A{l1D zJbKdB^kNO+dEvY^+kfsHc9Ih@+SQ%)p6%)M&D>`#0(uV;aa_bFkbFs@__mK4{3i-D z-G&Udv`qQBrdn1mAi<)v)Rtj*8*uVhd7Ag!IdtlnOT>QmPCgO+6I}GA(012xZsb@% zSUM!y7>9zN!nP+$!_Ue$AFV|U2R|ti^qTrR(bz6DOYr0!fk$(j;YL0(26!DIotASZ z;iBp_{KA_dtF2hk{>WWOtWe-LXPjpFlfbAwsa}upsM49U+S2{I1AhM}8-&6F&(S7q zB;hslG>hek01xb~S^xW=G(;JUUNLVfw&(u1XbA&ut(k~H_=NE}$2d|lGOgDb#qn<| zVBs5U&v%<~2;uA4#~*<@A6#%Hl<#qtC`C`d3{WS)BDESqM>}X9`gUjvo^QWBUmO_< zDJ<{pzC%cMCor+OZgQDoF8A!Bf{mJ|?2l>v?plERPr8hs?O28cGrf~99iO!&I~Irh zzZU22)2~y--!wEJ(Nvuqn?1ZUefeYS{ug=5AWGmC?isDw3zOA6ghs# z7${VquZGEiR6+`Eur|%dUx&v z`Fi<8FPDdTr2M+e_vV|}OB)RXo5g11`N(G2?|$tcwgb+;Y~4I5js&(+f&8qNgzssb z<-%k{>KDt#Xs_#%ECg5gcF`ln{8IYZ{9!)&_aB*D5l~LUsw*Gke&O!I!1R)oF(+66 zCMGnJ&<)F@xK30aF7Xk>NB}L3@ z!$-Hm&h@C!;LN>A!(?435!3)uhEdjUzVf$p!^NCUprUpi2N}N&PTdj&I?xa1q+12_ zvfCj#|B*Z3p;3)oI%d?)Rw;uW^S?#8U=FnOc%^$oGiUf!pY5IPU%ji0xI~u30)%SM zlbTC8-K<5u8>2qXE=gj(9n5=SPQQXiW$zWSMnhT^Dj&(r0s2!45*snbr%UP@Z47i1rqP7YG(7OfSWKm6^%utzl4O2;Izn&3E`1TXQ*kTC)$6E1 zWdn1L2A(Fz7zZmCt`S=4r83m6fvBK}2q21S$(y~e-uTgy%cyK|Vbg<0{p}m&oR(y> zP3=PT2?ymX&tJR#HZFANSm;-1*fqjem>WqdXRKTrYt~zV>s8 zM?1Uo%UcKHPv6Pi)W2Sc{UOu{7* z)k}sKF;-G0bGQ6DR%sPxa%Hw?{6P3y!Ask(Gau% z`d_;X+;LL_pW)!D!50&PVLQT>4IQO=KnJHb3e7q$sJ!omrdD)bRhZ+zd!d4?KffKC zP^YrcKBfJx;hMgQd#s_yiYKR!FtiVQXSQ3c9)Xois^I3Hcr;;to(*18MTw9LK&Gw= zTQHhAx?+?v-q_CiPhlq0on_K+ws-e~IDK1hNW}9#=@aCXWno<_Y9cNNLN~p4RV=`A zi>}nppRQY-#HIa%fQmRB$O~fKhLddYkh&P|b-z1Us)h&1yU`nWXY?hsJ^bxy<4Bj9^lL92LVX`1e(5cL3r3n&W(JvX z?)}aEfWGy%$#1wFR#OrsbjI)Yhh0*rhdP9po_|ISh}jvsH$Er%B)Gq;k%`&K(mOU# zKwglB5WHeF2Rj`7R=}Du8-$Imf!uMfyc6XUvX^J*o8qAlcQ35wxx(ksCs3VZi{7iH zcPfrV!6ISdehuO1pTrUIR%$)$_Or<{H0LsSJcy~xToHifH+~1E;o(8pME-=~X(`L1 zAgYk|C_}ol?yU2J*L4gltxx+C5GJ_D6?!826XQ@uGw+9M`!gtmg3ATF##(m)E9L=xl}SlyGX*sO zMd}H^dLk-Wd}r&^-NnYT+zq!K_+#D|GpPvsiL03|wd9hjg zbCM{X3J9&mElY%t2+{|M;Rm&BsI$fn`0`l7wC>dXmK0~1b8p$qeg?}(G*fSECq#nC z;=5r_yE(6Jmfr! z_#Jwxqw?FQV(n_${4Osw3|41~!o;0tEHHJMPI@9lxxLx00Ae&L{eiu<4X1 z*U{kg<__SYAdQqp4GG-!~+IQaS|q)87EUk()yA#;!XQzdkiFK zn}*^4p3Yy`^nv#G^&s6Bj2Cao!ZJ4UCO(gzg#w|HUurn7^C4DK244NtX_-yGm}F_J zB>YSCS;Z>Fe-ad!f6=R_habibR0|G8sdSl&yGv<6{llnW2{|u9p_f`?1uQ{v*)ZsM{9a3BHvy-O7jxZW>@G1Jj z6jFO`OZ62K%<|fWV~zPWl-c%8oF(r)8mhDr*eQJzL@T6a87IQi_hwpS<^+b{Kz}SN zcXkg19-hNHKyv6_AF%`Y?pBdXs9+EX^Qu zHBmlX&WaD_2r9e^lvAT&II7Hh-jxGrM?A%^$1^dlBC)%r`#4D{3Lliz-fIy{V^4Rq zQ!73^UOf21eiy|*q3Ft3a&F^Z=aZ1{cYWrs%0etMk^af)zQ(O-3nbiXP67gD2;BY*qvfmK?aImYw7~me(#I9Q$~hl)yIr5( z!CQ6Z`15iDRZ727NdsFZDIJa#=y$5%Ehc~O+O^noui#c;J!DU2?zNX4DZ)y{0 z+7pt}ta|Kw=|s-l_s_Gh4~4Y|k%EY;sT(Epj`5{$XdWc?_m9U2Lf#mUaeeJ8S={yH zxhj%gHFvhNhuU_GF$sEG71fbog$v2u52kG}RQluRf{|(^DX(?uDGJVqLayre$~YBV z&bcA##%>+vMU~cvzU*0ui7h{8)qKpEav`a)RXdc9ZWctPO9*)fb3@TtaIeW9?lrlv zDqf4Ge`cyGgku+n?n1&tX>i7>(aR$SWV83SBvhhri&!@J^8piggq5*w$+9cwO-H!O zhJ+GvdrSC8vKzgtwNI>{HkZqlzSp9|!2P9Qz=yoVH9mzo`BxfWWYMh#eblw-)em2_ z&V}4yK`Gm1Dm%{rq1QN^x>{X`Z0IyJ9tGg38B3RmK0~6Za>nG`ctQe=(^vHFLZtbB z#>K982cE>9H~f5j61Wkh*-<{Gkrv`poLK6ia!+2bc#TxG$Io&-9vqx;4Ub>=(Slfw zkq8tnhl!avaPbFYYSWA#ef-A^pYf-g&7pSE%^F3G2ktt4V)W=rVa^Y*Y9yb?5{}Sl z6SEDUH|x~|sbMQw`Ko;#Pi$+K54%fJ0Qw(y8$a|=5^Ml^UTQw5waEJnmIL=orC>|V zZ(e)wryoN==C(YRH{Y?tU$WlMhyt(xYJQa8 z;&`>R8fH(fghhVu2;ZaPv>>_Ts*Nj?)3A? z^W)s}W5+)V6s4Dzo^?aZ>@D$QIa3(FFBLdlG|*7!{jP;ene_Ji9s#YAt2#1_5wsEC zo0s>B?MSPK%&Pi0o7fK!nzF>@{8xnEy89IsgsgNnxy7A@UT^$NR`TG|0lK3`YyaX* z=Pqwuy1V+{8e0E)*j6bGPN>iwbWlSn8CIhl4I|X^^Y!+WBX+K{IH5`wVQCAZ35oU4r7RrnG>AFSk%(fQlSP$9pTF?_8Is0AN7!J7C z_T?q6qC#=v{oGO)&z`Eea`dQ*pwG#XrfAXp>K@W;7)0sU7-Ao z+&BmrFf%cA8%hv-*ZgvQAbo94c3rRh)vplN7WPN!KXq((_IZB3?K!5XFz~T@a&EWX zSIZ@yyAZ@~+?)`3UVdvkB|?%Ny5>c=GdBE(q{5LFo6RPbs#1R0E1=kq=c z@Qz4_h9leu>o1h2S&vCcuWDM!vT!S9Bz=oBB^2<|5F{A!d5MbR58B#&o%SS9y~p}r zj=m9jhWc#vK!FC{!EzgQFdbwH6onCU3;{qt-jM#ppaME19MA%WzYu}bB|J1;q%0z( zSo%rfz9+`H%E}GB&5-E(#*o{#7y0-J?ie)!T*aTvdj$wn4|z-F`1rVWjml5m?y)Q{ z1|ldEg_bh)$Lr%3S6J?S9JQ#cM8QHSomU^EX@*T$M6xjsZTWQFPSp@zb2I{d*|y%J zko+1*rK2~6BDC=xF6)&+emh#y^>kUhMW6v0MbY`+-i|l==+ic-zfKaB`zrA|!0OEm zXDK$``ccTZVHk1lm1=uX4nVKRNmkGCB1_0e-C9X2; zmc{-Ji}qwED{1}y?=zMV<}PF?rglJ)_;&J#-T$tQHyIzSU6&r=7Yk6s)s50If!ol{ zGGP;o##kkzus7UbHF2-+K4m>JWWyPw)#dl9L!v%rLlrDZ-Y3hwUfcJUNSpZZYlETXSH|QBY|};N~#7$W2C% zUv_7khcI2sM$5#1e7KI`fMng*-$&Gi@;#e|14}c+d}p8sKY;jIyuAG0!M5FGY|#QK z>(r}nNC!85=jEr6`fSLQO4(9q{zcFCj`D_)a`4EOy%3J0>KJLEe`J#+XFmdpZm?iU zR=T;-XpM&8UE(L_?DuhaJv?MM4r9cqD5hr7SXn%2Dm4Fi9b_A0o;{YVN@c&^=R+hF z?1p@jMJ`&+3gmyXz1erYgnp^9%+tw*RM?%8XV9?*!91lju!wuqmSd~jqgP3wnaK{K z-{y@Lo4lxFy-{{)bjOGRo2IUp-ML?2;%2%`U3s;wRkVF-c>b){o?O|>XOgM%E zU)D}#d2I%$`(igL_tuOLQasP!5w32?a0ifHdf|D<&_%!& zp(cx1hTkV9c5Pz8jfPDj9?|wFyKWqNqD^bc7WyH~UB8A<#ci0l=-b2x1=iv~DlAMR zfk|V??WoGRqba_4Z(qp+=>LGDF?lRLcaGDnVi-*?H(Sx5f3{X8FW&1ZH43Z43tDc{ zf7#?mKCf0L096WSv+Y~e_F(16i{?&7Jkv#m&pOIK59OtcS9i^w%h*DW9-(nQ4{B3?8F8KWMb3_l}%Z9B8Zh ztw9LVF$twV{tJqWSa_2oXwOY>wxQhU+DLup;6cwXo$oO5(eX1ykA98(`fv6+88PtS zrxCXw#L(W=4(dj91aO#_rr|S_(SLWp{S%O-ia+VlgVjMl4Cv2y3X2t`sMEvhQ<;r9 za^9o=M*wcbH*F4QkwhF(h*9Hxqeu<&Qk*SoE*OKVYP}TZgl&vj(3$;N}^M2MvUeCXV`^w6{|;~vU1Pcc|dPFXjeomWz zZ~LHj(7I0p#^RzV3R6?_iJYgcMXk8fsVfQrK775>JoXc;DLi7w>>Ymhe+Z%?I6J{C!^k-*)!{Y|Fo@eM$y0wIweh0R9d%hnqR5asOiHS@Kw{+mFm+HP4z~ z02#S4D2~0l_T1I`URxrf#mYl=zf{dK^Zi`2 zk1;QSxyun@R6)PicN_2qobFz~I_^!7MMrhZBT@5dJAkWXut>sSrihyfsK>|4DQ{5kEl z2yJ&bd1R7uV&Cx8{iCk&8+t$=X_b_1Gw?Tx?f0n!*_yTc=Pz!&k8Pp{LF&g4KB;BQ zR#AJXCE!q!WnpkvJ<7^^+f3^p2pG5mB&r872L?1-#L-BKKz4Lxe_qY|9F zS%)@xp-N~2U|V<@=DP?12>DjgBEKk;%ePd#v7m0qQB$rOczmZl1AUuGEzA?d%(5)N;*YZrFsjT+Ck2ePP|9o z4xdlEBPm4L3qJPx;||P`ct!fc;7g8D4>BR}9Rgtgg!Bai41T@t@%E+zXYyrT&l?Hm zs{vJx_GUn!$f3DI2m)0J1(Dh{!rnAo{en5_TUQssywo zu6+0~K4NNXyp71(b%dZ%@^o*lm;ER7(F3**>a$H#LVF3dpC4^e*NWKFSjGWEBKrjXJw6!)63#wu^apSy0=+FQ$m3=1?l z=HY0-vy>ac^8dkzMlqByQ}?CCB0noVF$p&!mzDp5-7Rge6jfc>O?;SdyT~gn_DW`T z*SqYltM`^^b}OWT7#n}F&@{KR9jAD2Qm|CKIAh7}O(W7K;j84#QUBzKsN0-~?v^cv zNnaYv^xWT~D~+rlBW@{rnuhWGp!@6n*`JFBQr~b985Df_Pj!o^z-1#}2TSXz($^V1 zxRV`E-rR7w&$h!)8s#Z4Ki6tH1>G?`7IQW49qdT6DxIn>X$@Ox>t2D|Qeu%wH$mvO zrwV`{(tz;&rqDRw;oZz)+cE@(Kx>LSIcJJ-y<1ACD1lW1jwegd;6h#g{>rpTEHhV} zGH}m6@4qq373=Ho3l%$a;>j6b{x-%sph~_rTQ5%=^F1Ej5Rt|uAC@Mze@f^D&A4{g3$}Mlzktj>mm8IN`kCNaz;4M+WMjfcw~YMF$*{^8b+z*Zr0 zcUtnb0XZy}FEcLDx%LVx_`0M0-cUp+*U5hTUx6Yy=C!|wJB8YiGL_|2^81w+wu1vs za5zZBei6tMsLmhrAp6@Ie%>*+>g6QdGf}dkeZ75&v$2wYAgqRK6xhPI?aresGN-G# zqQv4QH-w0sD&V8_tLToTg95rm^up#2mNnxP{eE2^Iaw8Kra&K~*^pKOt*k%R4MHln zn<$w+O8zO89`8?h#B)^t-tbs{F{k*KnAkbv3$t!p7*^B#z0c3i$`lD)Z8u$s)@Ed5 zKO63V_MA19gpUJMrVFN0($zCHOj(a2UamgdHa-e`!<_!*!(8n==bxENK+7=0f;9;IVsKq0_8RP6vq= zB!|hjV`JsbaYBx4E6F1RowvU&$^1)nF1vko2an-<4>Y#V>e-JaS&%h3rb?gM$1{;H zzOIcAH6LF&y~V?&4Gy%XADX)Y=h}W>iKwFu)ldo|#B92-kh#pUXQlsBaOuv~q9l<` zRw2c$ow7kl&9(AUC}kFX$xX~a zbDo)8h`~^*%_I0Xz-RY=jg3n9MdEHzMhE&=z$c=uWjgpkuEzvun6sjv$>lcHF0S-Tk-0hkWQSvfrdJCt1@wTZ zL6#WfZWm(2VX9HDW?W%LKffCWs)NikUjr-fHMA0^38}QzLY~6OyG;eN^;)k%xK*U8 z_&ub)B}jMm@myAvzPR_pu1V|lm}jVu>&m(33zsvgg~GR_V3z6@uhB}rmhVP#-Ygc> z_GZBCWDVy$n(WMDEu^9)2S{7&ytTRKDm;6yAxL)<^~OJHL$+!QXF8HM0C)xM z{q2G4c)`Cbe+E!^-A=TMdqpn8A^`vK)8ilhckTJ-RRid7r-<%gigKtukk7%-swCn6 zN%+O$$FDJuM&kdBbqW|F|8|d{4MCut+rJKkZ2nxT2JCL?3)LfXY^oK$h!WDrTzS-aztg|d7f#TaBr!xS$&N3aEnfWi-uy zP0uC=8~;wv8m0f^QFzE%fExq{{K&z3g>aRo+9CkcVUA0ffc$pg?H7y#4^3C4e&x^% z5^ns!Ar9e%IF`n_exOMMw;c1aR z+>j+kZIT2(eRD$UJgy3OgB2~EOY()HXNCwd~2`8e_jkZTXX+H3XNd8ry8cK`{qQf4`*6el)?3(u7?C&tb``Hx%3E!z&CU^!0wD ztR}pFbZC9K3FotF-?Ve=U2<)#zWj?>|F^KJ{{e3Fg6eDsuNYYm+0MO5s+q)#{Tr#B zlECe7fcQv@rbNBG?g6`Yyv%R{yX8R;n|~gIYl~vdUz*~#u&EucTAl{LY$hJhCQ99T zT0XTXr`Uq@;WnQrQ>KrZEMruZp2YLy4bXVGQZ$T{a z{%^!&W~{OHeC=IFv)qh;`%j%uNMMicpWgJW6shXsEN@=jxtB;~>=9*5Wwj=%pA6g` z|9Gx_SC_&lPK-sIWJ~EthEpF)7^c3=0SVXS_oO69WZmUE`n-^xVw~ok-lEj%dH3-m z4a<_locIpU_6hQR>&uuTZJ=GYHoubU{BgeMf%{_+19OKho|)k1h7c5MR5y}6jRlV< z1z1V4+>t{I%8oa7VsrvZOs7nq{XN^!IW;)>4xbKm{Ghwbf3}UybXwf!_f!MAyV9k8 z(L-5z|BC*TnhB-}ZgVU#wIIGl8~O`s7Tcs(CJblD?^lj(ac=Jt^i)sGPOMg;EwBLZzNoEQW>-~ zwi+fmP4QVpQpV+;y?@u8LPE1g_RY((&{;?(-JuYM9NkFr$Nz>%r0J%uJgdCvY8ST8p8qkNj*MS#`qJ?EW4@Tt3$s5tIlJSH4OnjUWJDj!*o$uPcEm{F zuer|HZ0b+dw9vvX%VuA>4cE)&H!RtBT}k+4^!|d~l)aO(Po(I8Vd=OK%<~IP0{_+< zRZaT)m96)OB_EQlJ^Z{{6xEwb#kYwvcoJcvwnUHc6%2apR?VD@ICJ^q>k) zNrF$>l7#pf)9EBv-0;bJ3zwY{khy;zoHv}{<=JFONLSKjd_5T= zZJ=1M{Pe^v@Uc8#xSe?G?gDTG7;%Poc)PDxyYkeMzc;km*@Tq&^nYepl05n{5cM#_ zDY|e;C_DX0({^H*?0^_0Q=L$j_)1lO;nu8mHrMI}aUy$~KOu^HRE#l!;Wi z6^rQEaMZU?FtHCH~wS)^dV5$Bsg;_v?9afrNqkJE7I=A)w*D64 zq_S2bLSX&UTXOyF09EvYJ+TcCy|ryTYx9M=763pndG&=e^L4c$neuF3V?e(uIIFx! zbJwCa@|~m$c`t*>WBFW2BM}rbbsURlK|Q=ZLKnfyrlCpd@<=d$c(GP3oZO~oY!TDI zM2pfBcGx9Es3nV9`sQlbT<1YVYX*j-`-6+Xx=GcSdG>R}=U^(Z`7$oGDI(WoPE|-m zTDF+VZ4Ik|Q%ZPG{Y7MQl|Eg21=nB;Rg#)Gi>26NV=X8cLilC7~&t8rF&Q2AG{8+Hd*(YN(v{!@D5z`K$(Rt}?=HN~6w+_L#i%kXj&*iYd$RLJ0 z?)*jMQHQkgQBN*F85@i&m6)Fu(qya-TJ8G~xWe+@c!s~f>13s_MLEiN;S<6#MRPKN zXce$COuBNsr_`1_ws-MkyOYpi4HmwDMMVv#vMsa;a{#?RJTRiu@PHVd?x&pE|=f?^7kQN0O)ZR+@dWO*=~)+X*S=z z?kQ)5yh));$x2lrh=NaxAXiN+{1r(|MGcii3WXoX@rm%+Z}%6I7Ah|RnZR>YgTrTL zK^bGwMs7%}>RjlMOB-yaxas{y_$P#9IGidEyRKKdbPFje{K5*~`v6y8Bk=xS4jgcd zom>1*@R<24{M?{Z@p6#*xytW)kj5nm&t z>(@metDB`qNy1ou2B^ypsS8v!s@=A62ht1hr!j;Oo%6yhc!kf8I(_Yv%*XFgy=^T-JNon-EjbWgcq+%z`5_L;L9n7XE9x^U zEhDRR;ZyV7d|xi%@ueCZ!q&$jI(xAIU!U#v^+_NOZFMjLV2h?8rls!)5;}{pTy`Q?XQiW43X|C+< zgl*W*W!G(ehf>=%pv;tsao_2!9(Glam3|~IB|7gYFYGSQbQJ)wxP|JKNToCk-h{Wv z6P78hfHb$op1nD-IYV*l#DF8b5qXT<1K*@!r}J^$6ZI&h^gJjffG#7INRR^ zou?H1#zI%Ubk%;+Z;MJU^?$p*xUeFF?QzPE34e7#b2n9#q;$o(Ee_i|aUWNK(jBYD z$I(|aTIkbUiiy^av2B9C5K+au>a#P47$f1Ft`YqmmwRVvDQhD}USJW`mc2<7T08ZW ze>%?ZH9zV#mD{chGE>uUM-G?BA4b-ubCu-!L|N{bVF-c!&PFO= zZ)I>XMnVIOzd2FcBb=>zY6X&a=Y&l%(}G}U`L6`nb1Js0)IF|&eSR8L$e@2)jIaIw zc7A1*5_Iv_ndC;dX(NM?);qTgvI!YfM({CA);|&5Nd&uMvf44n`v!g^k9r;QVol)r zELP@|bYkz=L6LW`F$0I&ca6an;C7&_8hD$bPRFk;R`(p1`CDqP5*dlG!tI7(?z8eO zzbZRe$aT@7Q%fn~e6`2>xclOQzfcL;l0%}~MTzj4;oC_Nf=sxMwv!<3c`l{f;_qAv z>*W!0ID#Xp2 z8rHnGnBtWvpfSn56E<&7>iRivzN!{$crXcR1I1^5XH8XXCKD+tmSF}aq^WO3ps9#dL7wtow`#a7hL(T>lEzBc1;KUFwVOV<14Dj;KvTqS;q>UQ?N4^c2L(TKMmyIvGFCH z&{U-Au7V*E5xy+5tq>xbJ&9l=U!lgWIE?&a<2l~jZ<=@iXD_XK0>-ubTA|mnQ!nol zW(MKg-I%Z0#;#@OrRge+!gF@@X9N1zcb)*He zfskd?Rs@X0BRP6)>Q8Fo$;+`H=HC6}q~~A&1Ku7oR+8+_#%-LmfWqntdMnds;@anF zOz+aUK~)GGx7inxKfXx(m1&$ zl32CA%tyMSko41wSK2*g3~Rh*nEZS!t@-`r_F-0`gUXtms<;20*{#Z&bBQ_1U)6)% z*}$3Ik-4S#TS6$Mz~s^KeOc;^X6OG9yD$;4jBhuiyDAI9={0WXfzSxIWdq%cH@^!*zx;wbo)zbEq8H z@~4_2+meg3V;mKR36gm^+rE3F-rMXjLy znN?}tu%z8t-BFQ4S(XOe`$)?U^;u#_?HNNyI2;tqg_&A_7r8g~3>R7)Gb$H^NN61k zX)}*!{MD7K4)%bmD*G*J;J0U;MOBM>>;p{bh?Tblqm%>m!+3dfU945&pc!4liy;UmqpBEuU2RQ!Oaa0DzZ^PYYg?qKJ5z$r%-gO#V2 zC<_m2_yRUFPiQ!94WTGv**J>4+8;>C%6=t9bSZ~n4pNuI1@%u=NP@b~nBoG$&4jb- zcTKu{RRA3mzv98=iNMQHqMDUfMdSQ16WV1|vaGnmrPTbq*8vMM-w#TyJgm?`@Gd4n z^T_h+Z=wu!<}<@+UR0>2-Hq_62P$}Beq#UPa_WC0w372jec;WV3;#kYs9-2Z^Po?P z16obE=%z;(mv^?`!0*3`tAQl!`y~g^+ZY^;acwAL0$cqmRvC%rq1Xig-8D#?pRf%@z@*a5WE9hwuMc63_vBy?uNd z0h!WU!1PQ1O$p%piWqB)Z?3q^{Mwv;o3F;e0&F!9xzsjW{J|bdyogr<6Y~|!h44Do zVrPuQB9Ca95H-8FFS}H*bkc5{rVoEP4o$qbz00r-V!s@Jd==ZK&(a05BmritV9)fCn(|N& zqcI$MrAY#4KS?Qa9UA7^7=k^OjmkUXL?MciZkR6H*E;PqVv0(WMb3pA zv=y7B1+9PwcmYor}+Uh4JmZ~#8R*<3A~ET$yG z_%2gszXXJhX(@c^ZINO(Wg7te{gqoR&uCZuJNz1~#GB$yjb(OGlC2fD)vKM&+~q6~ zoXEmItK}jfIJ}AL4T=-^K+@@1zeH?hQA3h@{!jiigYMV{PtX=lFq9vV!(Ww6m6jNK zr8n(_S?ln>PYYfs)OqffWq3bkb%oZ|P@1V(jr|eE&gIk)nG%*@(RWz+5l)mx0X3NT zC#UoW{)+X~{WB7Q6>c)Unu~Fx6+w4DXT7z>S;m%xx4Dnc#(rSCG2 z9(nmT$zKTNkB6iT@pT^8J024t3&TcYP|CqKcY<*DwnX(jS`sww>A4;Re=N50J5j62 z)cl&g=?;!Q?RnPE2k)$aBZp2oXDw;%A5`RB{Y+Z$BR4FyOlGPv8_T32k_kZ|c~TsB z`VN+i|DHxBVL)0wD@p1oe$e2T4z4CV^ZlxHahiYfKCI|+-q-o(<B4xNzkuOi`cW`?nu zdf08EB^QE7F3Ey>wH_R`gq>vU-(6Wom#3G1M2hXF!c`giA^YG1{IXp|B7L>P1eY2{ zkB+~Vj0x%=0xh=4fu8q5;^6frvs7Qd4{@GRrXm#4uX5F}`+7)E>_Z|^iTO2Sym5L; zp|l515<3-zdV4m|XzAdkVU)Tu4-L}@@2b|cuLAGerVq`+ zb)f-7X*NozeKxRMAJRd(eQ%=8)`cf1N571wmZooc2`GJ_Ckv&|ztA&?P~K9@anNWs zpZsT(zX7F`p@j*_X3fwvXm6iOA$h6XE-~Y|io#XKMj-ZJ@#brzkNUB~%%7p*(VMgp zwfD_$dpJ(R(hWKzKuDjq{k05!M7GqVh6kx?F){Vb0?T#%WOYH=-mP;nNnY9e{zIRq zb&L}Cx6FXh&SPJ|^#ot7KJn;8@xcZBoHDP`iPmcMS$&r}wf+SkTuP`7g_KWi?wDS) z6Z=dRDf^v4DlSR-X1*gbs*>a%(#m~fF5h)q&s|{L_3W#HLqVQ)O~*Au60>)=&5Nll z%IfgeQCLr@bnGZs%YcwP9e{1JTi|o~Wl$_|Z*Rl1pC@E^RtHx|BwXz9yA5E(cZOcT zzC{+S(jy%9&AOVbPmTlTF~{ck;k_L2wjhkpoMa-3Vpc_sl^&FfE{em8xOE*>LEkD7 zNSv86<|W^1FN2A~RFe|XPK`|gEuM%A=`iX;OlqjmAXxamiB$IB0w2V{cA&)G00sIJ z(2_r){u>1>W!F(w1=UszUrkLdT+ZQhU22fZZmWhCU=1;gl;Hk~Yvhl|5Zu-bL;xd7 zosdv9w*RzzC3^G$@!zi8b|{uAKhtPlb0xRTGVA5p>fg zbM)WAH4?Z~Asd+ML4`S+AYG??gbtxtQygR#dsaAZ7*SAF40}-3;^wCW{ce5R0C3#IRvZPR>`Xq-}AX* zt1bN*W~dnSLH*w<}#O%`(FH(U!am&CK*1qry0wc1w8T-$JSRyMfq=S(@05&2oeG^Al)F{Bi-Gd z(w))>C=A`;(A^D^l1ev7H_{#NjsH03JnQ}L2iIbL``-J?2Bq!WAeecKXhY#MOy;_GR~xhm8s`M`31G+oF(Nt*#C<@tDEjM^+KL2 zKk3O$tN1qF8Gp!UCq0TELMi`{@0X|O&*G&s6* z_KRw?HH_C&MWlt$Ma9rw1{&Uwc|_2hyK;IWFpJY`lQ$w!A+p#9D}^|j$8pLmt4eo9 z{@7boX;HZepixkG0Ra=ffr?ZD}C5M$d^8M zA)(ScOk$OB?)Zo!=0GMla~hwgQa_CRtw9`tCa}OId$Qxw$xx5L7ohUHie*Jt<|5#@ zz^jJQeyS?MfbW8kQ|6>bzF4gjpB^(ra!8TXuQD^bs1!zizJYrjGFHzJtX0`pGIyB?Q>61)We+~U{m-OWpeWmk zCwsEB^eTe+(^qhdc+7JzWflI{)Dq3^FwN%FkYXK7>tUx$L0=4FCpn6zH{O!rgHbHs z4!*C5T?BlDAy)B;moEl$wIoiPbO@R%u^K>zgZx>sYjUz0^k9RKWR&CgxVN{}=PQUP?{V0|Pv68_{@|x>fr{Tg zk~PficqI&<@PYreDaM{4>(ZHPGe@sI_J@+gtH*ee_8rrGo%d;7F}~sWVvXE z)4sORnjPyzf!-VvN~I|gYEwRs1p3~6B-tz7mZ@e*UfT!mFQTl)to3zUQKd)AxG9dR zIiu6OoX?EDg6Do&e(}C*sgC#J0>P+8DAHQyg}s7!SFjhh^ZSQQL_Et-gF&Mu=-Ov= zUC5xVOF&&|>Nt|GfQrI?`OwC~(6arSs+!SVa00Y2uzq4ryh4rZ6vxoc=SH#RqHoEb z)^~xfu~9%*Vn?{lk7sgTm;(;!|1j`#u>`j{plN*V(~7vEYN_3iv`F)ciFAd9fK$i+ z1%TUKGxh+P(cwRHVso!`WWnb7ZwV@0!~-!9yt4g2GeX9%xm4#Blo<+>^+^f*kRY0{ zII7p!0@RdrR__s5S$DBO9E(RCRsNX|_dwD{A+##o9?Rs+>0R+#YE1mB{Q~mtVg`Sr z&W30c!tZ6MD73-P7|}Dy{k0tH;czP6qU-%0r&W8yQdHcjTemWNjIJd5H4^rh0#*;bL^;QAJRuPF=&SaSx*CRflTm6=bV@V`rsW=vbU4d!64 zjPRdf9tB+d-yhx~?s9$#ZiyEDo}hM6wV@YujywE-1D>uZ#ZQ;5-%I29_yLY(mFXcZ zc(IlHgZ*;4NofVDqxJ*Qz8j1L%o6jnV)=42CSv{CZpnw;QMB@6@blYOj#d z^@xZk3>U0Chg;5-o`-T2l$@MulAaCGeL)GXoI0%YvNblyp>)>D z)>5zv0&!SFtKZF4jn$Z&tmWj$EpMJ38-(qT4+19>Oya*M6X26E311b=FzcA}9jJ3t zmH9TCkU`k~?Jvvm0Iw8(=F8Mm9B4Ot(e9z^r!ok3Ba6V255JyBrl%rm4^tR7%Ld%( zOZLAmrJX;QQh&+7!dwPdU8j9;9z{Rhgji2zg9(9zkWI_q$R&zA%tZ=Bq+iyRQ3#MpqB_u zwkyO4PMey+LuvJ-8mrGIWZ6*uF9MtC9F@My2JQNz_({I@blMreW!Yr~43>+hx{~Tm zpH)2xwvyW(jgaN~+kdX-HA z2dj9y5$TfOBY=YMNa>|l7Lnb+5+EzSi!GE~mAi;W^Y}42S|XOU15U!K0G zCltW`c*PU5#3qaB@C}|S%zhv5nZ@iiO6%~MlUw^Dis!cARXk#qy zgvw6p%LD3%ps!xZaKn12qN|B@Txn#k$xKOYu@gyeN^2f{_F^2u;X)r>`n z);|F(v2K7?ip|87oh3#osS{Se+T>tHOh1CpA4p8Rkmu5uT;PAAoB$WZ_V=gZ#LVlbe+be%4@V8w_t+DPO4m3LM2;pJfxI?ERvY_xFITDosY^01o0Ka*{$qm^DF ze0N1*$mbOY)#l7AMwFFK#q&J7d{3vz|2EKj*!fD>0v_%c z7y8%8e$D1XvhV>JG-?%BOZRVcb!KenXY{Fd_CpB>d?FET@Rt;7i#Jk|bz=HBnoc?iC1mXyZaAoqYM^k5u z0|01yXmTQeTt$t;qAMK=b09KlE;Jy*sOca?dWjq}b5cKsyiPKq>_P~}$M>_f-1ZdO z4{WX?jnwjIi9Y$m<`5o2^z;8P+$ggBV}>_Z>6Q#X^IE$`lIP+~+)zT`w!I4f1y{yw z%oNNhFTNdmw}240FSScv_Tz-bHrortjove`2>P)%3*-8#!<$yE^N()E;QoipX~$1d zx^>r^e(6&xOFcSF_PAjHwg06~$1lFYqe>S?LL5O^)Qv4G)L)!L*`chOnRBN>V4T$7 z&12@|Y%2D$ztXs0RP{^NAuAi8Yr_)UK|aIV!-|y%s;+)-sf2H$KU0U7U#cjc3fE1> zd6A;5_K_BfYeMy?C9JKp$Wg_JN}7(CpPaari6eZL#UL zFLEW4iJGVy@)l3bjm$q?0)Lnr5NTf9Q`XARv{x)OPpeV=t)FBvZrWT=)cXDtk6l(8 zDf+}?x0d?3?h{IdV?5XgQGNBKKzm#%_ZGwj`*w&E5 za-8`7F--W0C>L2|k!7g5W)(;dLFlfqi@D#|(=_E)yX3cb8_J_AdJ7tgt7Q6JMb5&Y z)>3xLn9mU(_=SN>mBqr72sy3r5H#=u#74aeDij^iK0t+xb$?M4lok4K+SKgld(EAt z)^>gVjiZJSCj<#kr;oz%kHo4I`M`%Dg!&!#^M~lv5IspLLyNI_In+34t0bVFp#h** zV2Memf02vxgQ#^dubfa`K)ru@OZxWb!|(9^cdE9MJ|L!Kl|2(#VUYIPoHY>nUyB=* z_^PAd6(Rn!NNowO{s5!w9f>0Ng&IbD@zVx_rU33OxXb`hO=o1VWr3CU4)U%Ruz;@R z3STvS;e3Du00l0jUN&PfYh?;#>Q&83U4_vstsy}n(j`UBgU5y4@~Y>d1h{A&#X-Mt z0+gy|W#SxzsdB(yyMfGCY}|E};2_a(_%u)($pDfW!gg)=YMHJ2z~vAdLPNj1lG^fA zB25Q2L@AvsP63p0L2#V;v9?T(Q48fT41V*2eQP@%d&Q9-$^c9fY;6%iF}7V#<~KJ9 z?wU1x@VAZQ?(u>;*=1O0jm*n>OGSH}6r32$7I_^&sr;msan6Fc6qQJTM1?`Of$UpP zI`*&pN(AO17|nP;USELTWJ74@c$BJ0cRsX7=qFWaY&hc1&8$(jR*of2Br+KSvuLsgMX?#G_;#?93Swafe%JioQR8InRp_tR-Io7VJ5{`9-2tdsVGtE>DB( zYu+%L{edB>s_ArEXMKL@KHeScB_xcS7Olo@pfNZmNhl;6PO^c@8Fi z-fS)CKVZnBh%$}E7#nRe56Qh<;qyp=FPYyWy;_O6mt^>9p%MR@?+aVb&Q^d^w;H|7 zeAfqVBEg8p`u>Ab+i(IOp-1_ICqM`GH9g*a&Z*^Yy25^gHDX}}5 zjYHB^XO+{GKMv(evL{NvC=jW4T!+B4go^P^JbVJW74WhUme*r0HO0ff1zwF5tUG`sWo_ z^$^I9%peaGb<8bf9fgT>w$cX01U>NU)U(%CoOn zp~8zEdS4B;I?RJ@*ejn&!BP^z!(fr+#O7p|-n%M)^wEAb=ZZ+jRkquBQS7$>DqfL( z|1UOs;EhY~)!+ai}?5||jw)B~1c1ihrOJwrMjnd70HNE*8aN~ciBpBoRfvTJf z;rR>-YTa7%N>p;^aj#_n2!F8v;5!$N+fvBVM!)0v(8+|Bq9PB1O%?&7sGB2ZgA`mC z=U#+Lp_&qX{aHC7Lfq0WNFT1Vd zbL@797LRqxoi!aZOX1`d@9PpCf3!bhxGhKU4T;WPi?Q?aaUus%M@t75#7ecWIg6s|bJ`_ho zo&!xXK)UCkHBEVP=+`W*>hJ}#7HdjuNB)JrsGHNzjlgTKN#8)~)&##kazGqoN?539CgPk(wWY16+ahHBL@9Sqi>_imO1WVq3-N7fyJqXJN5yi-QQOgaP<{T za8B}NK@tSKQVGs!vO&jQu7dr0iUY!{twi}Rp;)7)o5{D^p34YN0PWJvA1)cnYYT$m zm+tEK8L_B9{O|^FwVIA_ z-oEz^akVfzwJ##PpX;o2ibQJ!82gu^PTR!dGn97(oHC44Cb;invcmI*`XASlJZdL0 z-%1SC_&<7&jt`9Qj_=ZOQbNb48ZAP1o#Pb257g}@0pO0^(YyTPP#Z(`tby$-#bB5s zx?MT%*YN&3+(`?2l!1XA3NCNxgLF+Q$JPIM~dRJhQ_2mbl@;fSPxE2>K-GcpVFD`RD2}Y~(eaeQRwJ;oHO8^7ud)l83ihmVU~r{C3f=C^x`& zrga?p{gnGq{wjTb4YX0+1)Kd-+uV-ZQWTc?sD|#OCgI`TP!-Vy3-+(`52qGsZ@A#g zhE`uRL}y0MAz`oVRbputs46zN+x?(t`JUO{QQ4-Q?q!fwp9N8eNfATCTqJ+^B^>JZ zktazQb$DR!kp{UgFSP}<{14W+cw$!PJ7pT*a204M0}W9#Qe?>#73AtX z5jEB(&rFDz_ql&6XYQcj7*F%1*NE~({hCSyI*G{J4#W%nb>+xwqP-lHkj-+zK#=j#gr%#Ex_c_G5M9U-^KrHJ!$<38Lw+V zgQ5dVipN1c>nTe9XpMMw*?DAJe<7{uXPmm8(Ph+7Sne=ka%jU?p;d=C-5#PLB^VuE z==d~9XD1GwFyDf){&sWT^VC}Utu?@#&)&7MW)3eEHHv!B$4s^*CPcSZ>*lh zT`D z_>Ix$T;+(%ap}bvV7tvI z3|NZjur#{6Fs9XKxZat~8@yB)nDVK75GZHXxOH7!d)DfXTPg>Pfzas-OLva>^&G|q zy-#p5-QB4LApOM(y~2<5krepx{zk6e)87)DiWXp0BA8ZA9P&#--Z1=AK-oOKzgGIZ zIuuCAdfGGe3L7#8Q(}~w99{pLr0Mc`-MmPT`Ks51M?b>c=?JQm4T(JWeg>_Xv_^+6 zFek|W<*>9*`+D)09e_Q|`qdyjEwuHQ7b(aua=pWve=vo?>P&b0g3BB>{0;{aXpCRh zLxQ&RtQP?S70O@;tYF4pG z7MT0b8pU>fims39TsHlL4xH)4Ia}$uxVK&L>Q^O&7h7%~bxju?we*3%?p{}2AiIXP zmrB!8lATj9h>5`k6wx;F``}$8eXeo6VHifD^TPlq(^!WzuvHH~1^F1%d@fmL69FU? zG~d%&W^C0B+c8erPoW(A!;0Kz7e(Y;<3JE(vEc`#VIfcpB3=Ir9lY^w(&yY+iNs&A z4P&e(mo`P2n!dBMBLW5hG*4J?|J&ep;*{7e<_4jq0Hw3_(~N2QFH34u)KlD+1m)zG zKR?DV1XIqJDQTA5*v1x;Ke97SfC}{6Rd)qmjh7VP@Jfzq*~)sY>b(xT4vb$)Z)7aW z@twzf)?|cFU0`U0l!hXhjMzHmne=n2;nsFx(MabA&6nKnQgaTqsd#~UL#y=J^_a6q zD=pvFVI1eDFqyG|xzecpM}@<0BZjN((C1AP)!F^i-7L87ppw8WF_T$gY&C;5VP!ub zRQLfCAuNAYs^hkwbiCJfg(E6iO1A<)#AD4+9&qHe6Q#uRh0y-EI;Y(zxUNS@4OQy& zc#}Gdi%$!E<<$ZMUALij>$mFH5__t?86XHn{V648=7e-?IpcYzT4x8}+(H8lTp7V~ z9X4@F(8c&I@Q3#00DbThrfhqBC&x>7HukQot&T5Qc$IIe&oGxQFhWx*y zEE0#{;-^Ep(kUJ$bSM$WZZUBiYY1QX&F+wM&WU2M zLBqV(1FAh=hhsq2a9?hWGv0}P+huV_UDxg&02-Z`^u9B97d=a3k;KZ~53@MO^qQR) zSL;fTLtwQDdpqdYhL}CKYkMM%A3I0ZJQ`k^U)CNqD?g&7mXg4j*cZm=e0pvowO(6H zf+S!OhHaoUwy%~&*IDz{#+{;|px~Ks7f1T@3;IH0GfEol=B9(rc}%N;2Ms>N!wAKG z%%SiBcjLV`(Eno>L zF{z8cG!0N3C14ZcfyBPw9HZv7p_K{|Mg?kn*#km)uq@F$?r`cN3Sm(1p6ohdEFrT* zF4-vld=5cI{qM{X)0(NWXw_9z8{YHHtPlhJRK6J}c$kVw?>MRa8!U{Q0%52l<@npP zzuxPL)&DMhP+m+${R9K5TdJF`K)1H6YCqf-I-c;Sg4E^PIQXJox`+Q-*u() ziiBSPFB`DkHO1Lig*dfV(LyEE=7Ov8)htA;Z^}BC!j$Gv*+Z1+{n#z-WPb;nsM>N#KFGCeYFS~zJ=)iW5Z>QK^@G$~xJ20QY&K#SIAW5+ab24P8I z$pB`x%DC}eeCJIt)92#td$3yO#SAZ9m8DkpG>5H^5^-~6`_SmYW>v^6GaL3Zx|KkZ z=f71ZU)&n}iiUe%cS?Oe1+>1C$-w<>gS5^IH6hT9M3G1Xe((5Q81`BOyxaJ6i0)Tdv?uAXpKu4e*#8H?@2=tPA z=zS~k;Fbzs@di<15C-FC0H^&@Bxktrwm8nA;($iCCl%F-=+)S#TnN=;z^(5T$hoGa zbxrK09M5jq4a8)A`y25ivQn7PtcMhWKe2ro{U;`btr zP;U|V+6Lt+TP?xjskX5Yb^YwSVZ1T9l)cyev${oC%lZ&0cuE(h=S?rf!D8re@CHgQ z$8yB=-qd`w9Cv*11rt+`04zJ$+$0-$)AJLr&!RZ71??|aQcVt?(Z;1-}<%T zlasIM($g7Tib9-*dUo7$3vPLJtQAX;BZJlHB$1uuq$Zmw^2-*J=H;k%jJm;aFZxkEUrR z?Qo^B?cH3s*&rpoe zpDDcZjyx$=e=Lh+;q!6DWqiXNlJjIXJI0%&H1iv5ny~<#=Z){SOq|YBrs+nCHBIGaw@b>Y}#$ zIdr#sic{P4Ur@;>Vu4r>GsjHJ_k9Q+>1}dTj077qiB0-m(iSXRl|iKE15b+Ba(1mh zff4p%)A^@20I*ND)?pph8?jhRbc;41v9pe^FFo2d9pQMu3jIzMpWI38cZn7toKuAA zsyN;Ol=|HGUuzMlx`bSOR_u}i`?sgO9x3G0{|r|oQY3SBt`T;0|9Yxtq3^Vhaa(02 zxzMY%o9>!&+2bypsR|}l4GD$Nq$KWadO1!3D*EJr2tv@*CJ&i zuEAaN7M8V568fzYjxQ}d72Fmd;2|f`lBi0DKSH95XJLty&eiZg?6X|B(yNPNgTv?ya-{_!cN${+ ze(8zjMHjl9Z$ne%ro=FIByS9^k;)OumF~E_u|w4tKn7A5{-uWue#^A*V1$b;z4zU8 zE5qXopTM^FPta>i@qA6eGOBF$RUJJMkeiA}Gt_ps*sojRe27=haeBC;>j2vJ!<|@> zd*Qz4q%a_R2w{X&iPF|O$w!u)aDXhUczyK>Eoi?{IQ{-V*z4|O`KOIJoM~u*3VH6& zs6|vEbhKA`q;Mg;+#JMH-~DowUswFON<*u6~?=Vfz|*# zX z6~H7fP$0 z)w38WN6jLJan!#pjnmJ8ut2q^#4Awgub7DQJ>RD9Wc~C6n)84;jFHaW$QsiFv+f?m zuC;30$bDY1u94}M>yGd%jLWo(|1m>OWBTEp*~^91+y-w60l4$=e5HoSS1=_V5itG~ zM4ZRu%*di)VYGUnq$~*ScT&5-vdF?Rx8HDB!C_%#>0avX+bBdl&bATUGS~+F@J>0!O}f3w+bSF#+_1C!%CN10SRf=FF0^~$-=kc$rUK0l#bx`_ ziR{(CtL~5r?-el6ly>p%5Hfl6mHMA#Xu;0~Y|X>p#3w;-vLKZ>`QWeZrnGBvD9!Ck z%kJp|r=IX5!23`0zU&>B9NM=7gT`r=_#Nqgyj=OjgzbQ}f!<4X(dnIBy>Ffk`IJ>h z1FR@+FBw8j{@N@|vKMy+@!!iyRHMYX!0VyBc_l3aEMEl;7FbmlVpq`di_A4dE^h*%N(qQ`z*`7o55mv z8V|hgtbx_|j9gU_&46Xd=IGv5yp+7VkzCBtxcOu0%=JrTPggN^mjE_h56?%dujATs zmKey6La*D(W~`^Xi`)fNH3&pQUL1aAf=*=Md<`BML7)|*UfPrf+&JaJpmCF7tbc;9 zmT{mmpLyzL@PXWWTh54<61!HO`N1nfS13yat_LT5`wR8S25?z$>dm*0a)um1Rr z3xCI0Qwl*XE&6?ixNGqoO4N`H#=$a-*KIH}Ecqh44u|PFo|run&b7WpoRB!ovll0% zh8QX+SdzLX%IM|lFsmP|e;jw$%ANy|i0S@Pp7_0*#Q;jKoA8s`WYwP)OkqTFHr?G) zo4j|p2<8e@(i-GAn%er)vOGy^3V_3Xuh|lEe^AjgdUZ@6UAI?KrMEi3!tX=tfw^CVM?r&ZHm zc0pZI@o8c3-KG*djVOpvkvv>3txDdeeWQ@c^cB?vG}_ux1YLm5uc~5-6q{g3qLsc~8~+AX`LeKYq(8|)4pr{!V;xafpVx3h*=#gyd4AFVIQHEY2C3>G7i#3CvZqoW zC=AT*ba}|yycE{}*&(asYzKDl6Lhno`24VAZda2kb$=(L9a;8Y3~%cpgd)8?>DotB znRrZHA(1!j#=>&)jp&R6t$7)u*Skq&-X$#)0d()+=ID11b?SPs=jwNjADc=Fh~3tZ zUIvH6b*N?Gjmnk1dLC3D${rH-ow+}5eQQVNYzc4DP|wClPN@#lo&leu-m87ZZVs&dy}_UVd6 zI~mk(b$5xQlfOd1;DLrtd@v(e0p<{$neda4iLe1BR(U>7dC#InOWz4C%rg)V4W^kc z9zlf_eohmEo(pN;m?__^Sgz5?KCwX1Y?ioAxc<#x#@14-!!tBWzp<32W^xoP4jI^T zs<0kE6}V>FmvG4;Xk^yQ^G}S2d` z{1J=|U-6=VHM2#iFXNmo-$sNr{4l*5U8)6JyP9q;^@;zt5}na`RsY3cEp^#@hxm*@ zIG5Myy~A%nyS~Mq-m3~0?xJs;v|bh4^q{uPfy2u1@3;B{O7Hf5yk7c17C&`Xv$g+T z!9Qz1P;-JVEQ~A$x%#1^M>%6P5+_oXgVM5tCQI=Q%-sYjJ0`MAjrn0{&Q?XabVmI8(21N2b|!&MS_ z+b`o2l@0CzW5EFTk=Bo@vHsH`-4l-lX=1o3_!K!V_jKtYyrL-1Mv;}A{64Z@U+s2f zet(-Wag7P&TR-9k1Eo`sJxvdH8XP8{G||N^;u@68*cG{Iiv_#J4~XFyhHidbvZchP zq-;Rwv^?s|{bT*;(OBMvu%T&3Z~33ZB2PVFWAPi$$0_M0c|=p*;2#R?iF z|M}`Ba?RsuS*jr};{spZ+2$E>o3=?=wtcaw@Qr&#a7@ZAP?V6GrZ1vir6h^^`Lbe^ z;@;FEB6mjB)d8fLKO8N)=D>alGJ^k0cJ=)+F>KD}#>zUeTJ`cIG;SGgP?+lmsPm~a zOxaor$k51LynHt~BU@Dk_VjCb71ZhF>_fL?+=h&YOsco@nTtUahdv|erasek*S0c# z%5twDF?6NkIod$|@S*hsXDt73{yN=E`+6nhXAm8C5tyTz2UZNY2_Cgybx4S8cV#=V zITC&-)Pzc`*w`=xTd>kRfBNslYe7Re;?zS0%m7Y`k0C%5y{VpiEYS z56rV07A}!AO1@T?&WP~y{cBoi?Pqv6Cag6DEy-987@#SjXe`E_Hfp+(@RYMSwchLH<9He zS&dZQp*d}QxY$l1d-V$&{Em2!oKJnTDK;Nb{-jidGIbFh@A>&68|+;k6Mynn+_(kT z(Ln9+CQ*TE-6MTKD}I3%eHD@3Cx@+>h@yzGx*NXj{0K1-7^V?&%zHr~SwiqfW_~Rk z;sS^cHOwwq{K$nOI}ena38pyH>l{iEf?4C zI=@f*k2)jHOxdi4-@k#JsQ{xN;gyJTbh7d3ZRw>r7Ky(?G2}k|ZIR2NbBi6<6Mm@avm+&5pej;+sCj%Tk6>CdPAktKNru zu{V>wdvLHb%aUb4hLQmd7R!qQEh+=dQN-2j(K6ju&sPT1o$Hi`q}<0H;T?GV^2e_d zjiB1UR-d#U+kzKIkBL#jYnI%jDA4l4+taObzWkC8|pdk{<0Aqc)xcD z>2-5~4dmM)6jffDO=ktp#YA^=j^&*%vuha@9LdX?O`}g=c$<^O$TBgIW)UzW+G(KQ z^9079W{42rLP6r#gP7i0x98%mIrEl3sj^s~w@m3yeIzqT1akxtW`-{oxV-4SoiNur zp;lFI(xR~Q<~ODNG)aLIr)cvk_*s@+ZUV8HaacG^2skzdi_sfB^0IP{F(eSiG^dC8 zi-7q3+mk63RcYpumlsR3N-YFwZS7!wzqrCD(R!7C}5RqU4jQv;a z3YTo;bJv$)EW_?zy<-g#27mPzQt95>j3-<*W#aoWQ1>&@rBzBxAxk?;!DkFU3Q*d` zrDmORi`}tr8bml1Rj_7BL)upNC(08HIl;LAg*j|Do})*WqGSSC+Be7ngM1u|pzRul zHwC92<&5k#V3XabX@(DD;_@LqHOru)MdT?7^pW3dAcgAm%Go^`U;hX*?Aj~Uxj&IXxn^}w9tp)% zw`42U7ko5qVXGw63o5uf7ITUL+E91-;SjEoW~T=9EXX|`Hm0qU-+&Iu)z9r`Xg#q0 z4X`pTt+T@T!8*v}m|pF6d4J@V^x2@_^2oT|vQF*!B~0Rx1A~CaU4j}Yg7SJl5sirL zPsFP)piEyL9{dx6ag-$+h?mJuVzr>(rSzI}=1c-)8|*mXC3#aM_w}DM9tf@`XNL+A zUPmTBmT4>B?0gdanQ?wJn8z(SK$aiREa!vJF0zJQVSaPRiGmePNmJej1ho|_C>p*; z;OsWEOPEZRovk=WfD7iAI8w{+sc0_RxQ67HUQ-VcSU?OpJrcriT;YaKJ?Yb` zR_<_N_qHRHsDx=h5Sa0VI_Q=naWFHcYKMj+yfIsMdoaIek6&tESRD|R$V{b@_A^w| zk^7^7S=zQ6&iDSlncd9lEUP!8-vgmytion4cJ_Sja^l=JH#d1qDEL1sN1_e=o<7~E#h6wdwwW_+O zef2mQwyGDPL~NtCc#Bu%(=bO@AU#;B5p(qEk^_+FJ}j-<7-Df&5?1D*{`3rj+)|Lp z4auNYib!{B#n)I)Krab>Uv+B4D4!L=aVl35ZDY<#EvWhKF_y3K+15II1*VA1?3hgcwDytRyAcO!;W$4Oq13e9V_)%K+Mwvz^M8T z`DR7aba3`w^=vwPdhtrp;CMJjfq*i7Ef2nR9d!ro#cmy3X}?a`y)uO$9c5Do(WZfc zk)Z8uSCgv`MQd6*?GoH-c{;ifq8h#$H7iwj7XFsO^s}g6F5v@lTWDH}vf5h;dMx~k zIx|W$!Bo%8e^e?&DN$9dono{s^J!%3xpRTA$^t2+=4Po9 zcb?*&EnW|Q*)|EAhfcplQ35`s;koHrKrv{_Hs2Cvfyu-8TWa=8(W{t{$gN)PkXHvk zH@8;;D1ZDo>x7%k_k{&(;s>c(J!+J3(yKpA4b&?wphH-dCXG%4ni5RU*+!BZ?ZrU{ z&Yk78xw3ft+Ni3f+KIv8Sky~~F&&zCRx6*RdOMie;-nM?IW!{gt~*ivXf2#64sXIE zd~lAth`P?a=eCqhq96fOUnI3vlLFPr^DT8$E2>DFV%1E`BuZa9(({D+Maf3=GH%HerRhG$UlFVY%!B?F<0fYV{{av}nY;(~|vQ+dnlzNl(l^M5%WHgl8{y<>lHWVSkA@e2yHlPdih7f;gGDu zw>mU$Lxiow7d6kCQD|3kG;4252=(c<^C!;bPz5^G8y!wae!yyVG)F@0G7p^Id~96phz24b(as`-XzK80UpTgI-fo`v~TTgxmz}g z0+`ID^LJa6xQ-F4T_bn=B=(GXeg<1avn)GrUKbu&IIG+*;A_vG*|o$dDeeB%pu zmDLxy^+F(A6V4nw!Jf3D*cY;AKoCNv3-khNmUd?)1gH%2*c$4lYR{eKKBh4tzPaDM zG8VRA0)s};43#q}N8jwlx}p&gu zMwIR>V~_CT=J|rmlEuRi%9(Y*ttP&jfjEj_Z-wEOZ9cR4`vxrf&0$Cfk1iDgE$a&` z*b;wu;cy!4$gGvN@70b|>UL^lMMIMXE=?<~I!WiRQje?~rsJx(#((epOEE71;Y$tz zy*xRP_pa3nV8JK=Kw{xiDE|vU5&|`|g{5AYnku5kO31l+uTUKiPP9UeaTL7M8yL^S^pS1Y!76#0iLZycpPKKuX ztuq9M2I~u$o!@lpv;j^?_(6_ftOAB@6ad2g`~<~U_BBvw7@5-~+k=(#MDpq09w;+( zK>zz==1f#s&2sgrnKTrY8PY7d@HqDqBD4GPHDYTU1Y%?{u$h9F*4vbJtx*;3HGfkl zt8ZIV`2l~&jvzI#cPY z%n71mIcjiG#+#xOel}F2X0_LQ{FaLVQx%KlOKkJ$C=<4fm{>2fSauU%;VXJtcrDLk z`kSuC#L9@hyRsyf?1AJz>S7h0*g3PjK%HF zi@R2m>ckZVe`nWrrdpF+$~W7~$~_O%?otfg%lq6G(lj8pAwePnijvi%KHopaFusPE zR+j*!O%nIV&U%kQc`Bnqg5F)S`qhP66d62e&u-gRSyguXzG^ z8Ok}CitsP=8pSOO=a${C+P-6UiCKxST4jyqxFg2JG;ycj2_&9fDeYn3+tN~(x?C8T zPkThCxVY|3-)2E9tIWa%1C+CVg2(Bu5@<~Whl&?~FrM+awg)7LV|L}m(-{_#+IC10 zsuV5M)4B`>A{@IrzlHKa#=7hD7Toi)K@ESoVo*sn9{}eZ^`LalH$ZjvT9tu@Y&-nv zEnudMIMn~tWNA_aKQFO7VQu6W1+5feJzX zQ^e%puP1c|@WYW#3vr-xo7jJz%&*l33^cYX0>uGz^DYN@bumzALF}G!*y}E_z45az z^J~hy!TTDzrmvylKK|d@vCk?C;|D18a7mCDK4v8Y5I$|e4Ta1!Vh!rv5tcsSyD7T7DL_4@#>@xaH zrAJHrdH+9_T79e(*20V2^7CHdBPCxqMovBkr{#4AyOzpl7zdx}d#xP63%Gmshv-K6 zt07x-zS64nBIHOfs<~q#PoZD=I#o8jPv>{}kHMUAEW36oDsHE!rSe^N%nEkJ+Buo} zHC;MZzY=9rS^^waQVEIX138zYYvAcbsprN$PF2`-)|%;_IL<#ZtXi{r5NY!t>cz<}#@QeVsRY1J<>rOEiahtv_dFjug`Caf)+Jk{kJ>M|h zen;#oGteI!qwuw1F@rVS*#-yZgdDzoNNqDGdDA=~fTF zF(;#ocLT(YnvMElxM-H25~VyV8tFFzEM-LrJ*1jLVhZ?(Dlk}tCiX|ce8``KWEfLn z6pnAd3%!~Wo8)sbG)3IM*+-|+hC#B`r0-LfH0&(j;fy%yqL56(j?r#^5@!N3h~ACT zY|!-Pyqh?vuWf?HrbwF6Qwvk@;yZDUo~CnN<^p*!wKX<$$TfcxJ>_%*Nh#!L#u!4j>PzW8J z)`VEHl)NemdcAwkaS7E5j?!i1c-LeY^Z(d->!_;U?R)spjWi-5punNKMQP;F-QA6J zhtjEV=#cL2M!G>-QW|Nbn|I?U?)~21`=?{z7#sF}o;BB8bIqxejuRiXq8TcIWL{RA z_Z*v^-SyOSNs1{gtwIr=?&wpOS$xi;0I9;@#dSslp`{r6(+DzeI%^#gW{vA3tYoU3 zrJh%qJhH{sxBAhHC?teVnd#*O|wTOUSR7cZhW{8> za!$f-9y$2V+T5MyuMX$`xY9&|bIGlp7Y=>P`xluG>ry98fYr?&8NE|;$Jc~1$E=F_ z&AMDKnIHo>a4cIt_QhzaUReH-4gx~wf3sx%^{IM(-ed{DG(F?4QP-Mc3<)LCXqMsX zsW3I3$#`EZy_H;rBemQW?cc)4Sxh;i(;*aw=f%-M&01AdidVR5F}I{kl16PjK`1PK z4dK+-_jK@YF%LnG+8^TbO6u^xWl-!%R?Wxg5}NYI;LiN+jK5;=Qm=FGGspW|1Tx^^M!vnY@-*Z#|9%>jep;$e>D=5qiS$LP{A&QigVJN+UT#6h+=VpiA+ByHOG!-qK zId7}mO7Zs*D9~6Xe-{Ea$hn7jq;3YMe}`$-rgRlc=TEi5ghA^(E43lT^2Lx&$nY?x zyxX@G1MxL|Nz8{Z#gEa{49wl|EHLmwO&BF>Zsdb*TJ!N?FwhCnVuM`vpPS`hD(z;B zQR%g>t_+js>XusG*5?^pWUs+gZ#^6uwMD%H+NyuP`op(<9pS6E3un7h*x22t;Aeyq z7btuX>zoBH@7i&f9j5UmO|pO15ym*yF=I@h;k7aW{S2+~+oc80ik&@0bKfofj&v2j z2*mlAdqKcEWxuVAtlVGjmhP+d&EUQII`4pD;^b2Pw0fJj*M*UIXN|zGTmE5v z7;jYe%JD$JG`xIBtmDW~!B9fu5#)p9cUj5O$RCz;U)fW%su|ZJT&TvmykMx+B!y;K zD#sVMzGLkOk@B7(n2Y<5eD_k0(QZc;ST%@3{KOQ;Q34aI_xNqybc z5B@Qcper*QP#}noDfl@SaZpUrRRMu7g#fa??3$wDKK^Ad!f88J<>$|Af`_6N;O~Uv zK%fos^<|?f_rkITn)7lp&Z%4;U%1pvnwxXX=n3M#z0g0Yz$k1$YTR5kECg_)J~Pvy zZJv_OUUDf9t-7;LXE?epV=L5c1?P&2DA@y1r5S)(ZTes1^!F;|&oA579oinmNuCcW z$wLrSvYrPbQ5YrI3BeY99H&@QtE9)#Xb~x zzvtwpSfL^KDhep;p)pg$x;+jF5=Qy-b&N}r%fs{qOwtLzh_u=Ps3z56N1OnVtbC!_ z&-3AO%@y2%rycGGbo*V0P`un!($;AS?A(14TJB6J6Wu~j5!>Zkrip*$EkKoMGGn;R zA*~IR6{BU&8UW{N_G(N>3fMvLO|7_v9LpRuZZmK{dX&HhvW3DBJLG2QU(g7eq;;G| zzOS*xdqpYI{lNGB9ERTNzD})fe_apK^Y)I%PqDX9i~Epqt-P;b*m}WM7kEO3+&T~l zmmu|49-`+SOqq`SO43!euk3 z$=@~u?FCD6o0s9co!uIjcQ#SAU09ID*Y!PNcXPTA`tR%GWbq+xnks-~#w8ulv}?;o zRzkHJm&e!c*=>snSu1fEhv8YKZeqUyE+b(Th_nWW@RJ`kX~Jw))$O=tUi8-9v&a)U zT^9KICGJu8ruNGp^VWTIgM&#Ek?)S4dyD*>TWt4sXfktO4>>(2 zXAhsRO>)F;Z640*y1fbbTei*u224f1(%cL=mmT`@Gy%OSR0q@33wKxeM+Bc642*q z#jeU{YyVQ4zHUvyho~I%ue|i(JGA}9(+oO9kqxa_wq~xe0?+z~qG)|DOLWyv~cyi$|vZB5aWfBaki~ z#E{6?@Ah8k!9cosM|)2x;TshmxOtB}DI@}CgVr(@He+pY#L$G!r)XqedO?iSDuV>4 zHHCa>7AAu&Oi^=wzwW~|FrAC#3HYF?0NDv^zhp6tY1oSxV{7S&$4mq1M)WHE|VpScB3nPN{k&zoh%&U z0r6&-qE91KfalNh1O9vpH;g{*1x)Cp-;~dB`sOp+14wOCr<|aCJhazksIJ`tU#u%7 zVt9`olVgfLLOWM`e1enOZ4^<4MOn}l6>EGH(W2sFp1qnVLUi2=uT>j|i=ls&C`!hxv}=!h7EvUNIP;?5my#%~I5 zYYEAKd8cVV(9e;aa7S+f9MiKgT%U3f)$})gaf33B9fQ}(5~qkaL^RHla3KoktLH%j z4fNXr_3NC8#k|rg_cvSR^{%gU2S}ZVfk;ULBy!zwWmrgP44X=^A?v4KUX<;2ASakO zihqzv={t^Gxs#L(K-Uc1pr83S4-^Iks`3Dvb6}0xIp5xd5)xW}2Z`*QH7uc%f8vjT z;aJ?w(~G?t{0=?OnEsM`3B24Bt+^TpgNfuVin0uLxCaW!>E<>#@XU`#rcw_0U@2uu z7)301iQq0g%YGesk|4T{wAtFu7mwfcl;s{gJTK|L=#?hE7qa~Eqv8WE_Z4RZ{}O@5 zY?UpUa`w!rgx2<^=D>y(RiBsd%BP01olMe#h^(h|>xG89r_Oi3gXetkmyp%?nqxxV z@iEtKoS5_E4&I-@f!v`qVH9_+qB$)kCOG9cvX)zTm3eVw+vkm;+lDNlI&kM<}6 z6O1O5YYAOFEY(fK6s6`3B~*f>eu>(P5%`<2{^Im_ySd5;KVBf2pO%)*rV0I8EGKlF z2yGz*u4a;E0KWh^Rhq%cfA3Zj;T+}t?I6X~>hZSib#rzwDJHGmAe~X1&apRovR&1o zbf#`wy$x_nOF0@ItQ%yFyrgk>Z`$P(Iv{=fX6zVPX~mF` zq0Zqz4TlQSnYR<{`kq=Y`X1)+blX&^N1ws}_Of=nPng7GWhsu39QS0H*K znyO8M+6KKmYShG5>++p9ajmno`NnP!bN=^UhMQCk0vxm>`4)Ft(%(%P)VwA<{Cq1v zs3XJk{n^ovvuXKMHNO~3KaN5cGg()e$YXD1olYi-9jDkE6(*J0Y^(QOe70hEqQm-F zf{+Cgh3=+(iD4O}u7(AegRDL8Z-WHIJR)ScC>Ip0Bk~WzCO>3lRH{2M95oPXLBOGz zcz>Azee($w%J!e8)h9#kaN~C<+Oy*B^Y8Q+M&*J}a6ZxrSmJ#YE;lwIWhi9sNs~Y~ zW>yd&9uk=fSA=jF!zR`9+3WxoYi3VZ>?*I~G;IX1DRn3c*ct%qK!`r2q&8WU2$BP=dwN%3LTQKG4#DhQsT7*KWTpL}5uJS!nL9Y)P`QuDhU0tF!4;eBCL z6tg#adRz(Ru$a9Yf61~95L0m2B9 z&A+*y2TkrgSd(Kjk!;<8$<=mz964`sIRG2~3*aBag_RHsTqb8DD&No?{L&40T0cJg z*d;La?Z`yIoipej`@nS3XDxZnkZ3uvz;(q6NllbOHAxx&@WjKlxz#jfZJ4uCKr;yD zIU-hN7@T0!A$7l+M=!xZEcK!4J@|HyBufpr;Thbx%YiE}9LGsS910bp7OJdqGHGS7IH^*-&|cHwMV9Hl)*MQ01 z@yK(Ts>3l>Xf3*}^OC1A z;w7&jK<=BeuEj(Pkd{uQ3{b21UQ$o9^;Zx8UbP7PMan2Ho~cOmMd|`$>$D+0#M~UA zQ(8!7Dc)sBr$G#7RdNAgF4Vjqej-wl>DT{$-RJC4yE?TcQkm7wA3n|BQ;sv!n2o;S zYM|!2(uitWPNH36QZjHCFewC4q2A?bQpAF%npl|zN!$a=ns-C z6kw+gV3e?4U8z*)j#QNjTW#_wrse5a32z2CawTfR#3?}8e!Osey5MLkiPmefpjk;? zY>=INU5zPLYKhMxHl36Z3-B>w7P)&$lC8Z;!&w#dYN*UJwQF7r_{K=pcDDWim_HH8 zPn>9NN?TB$gZIROJS6It972@Sykh^Xwxr}#Vyft4o@Iln@+4o;5bJu`UMOI=H-7a3g!z-3{yw2x{g|&1Guwo53KMteV ze`R_l6pE*C7gf+WSw##Ee{?;4at_=9ji+os%mPh;$8X~Of7IasCsW|I6DXq>*l;~% z_7NWEpbBpdt*Pr3>fr?#r<~4}jlH^TK+i zdBR+TW`=uW|ETMYI$*N1ZF&K+=8}kUgVwm3Q=F&HZBWK2wYMW zGVy6CW^=Dd-ZxK;r`!#JzR95E;RS&!Cq^@S=<4CeMLa*0S}DD3MJ|7%U3KDYBfTgk z3+w{)Mx_^M%P=c+z?*SkDtnpxeY2+?=|yOL+lU`K<3GjVG%>U6+p15|gbeL%f~QIY z2deM(dsZ3^> zuYSI#kf;xc>E86Q>TnHdw>_=uVqq^VRYmSRaogTwGt5Wtj!kT*PFx7 zH$f2SY9c#b0?zc=^-z=-CIIpwuab$iusWh)%g~X<5fXItf;emZDWb-;U+4!avb4ktUkVKGb zEz@TNWWEHPe#RiynKtD{p&}95`jF*G6nP>sT1JHS(ii|6^M!I7rOsvnwP9w9e~}jM zJo%F%9V*H30Aj8-iKMn#!+qT8KybB;9?@ZYV>;60g5dwCO=zoJ83<2Zb4i!NS^l2G zwd_}nyvRBeNhQlReEB$+Q@Y9>y{iC$&9V5}p9Ufzl{nPHvdj8erm7*OsJr;*i5VD!|;&K zj^3JVp|r~L)i|w}>y7ZNdYFF>264&X+Y!$oKmW81Qwyhk=a&~VJ9cAbfd0bdTh{WE zHKs1KijAlERC0CVRVPQLb(KRQlS!@Or4{oVvVU}1Pifq;la!Xf#7PfN1Qj#O(g_qFn`vE0W4VzSV{-$)gKPq@C5gxF9oJ*`QSstB#a4!Q8O=RZ5$yH$wHrNDF^j@!Ia1L!VY=%C zxN^H3|JsT4D3;L!%v^L|-?$cJvfLVc^=ukF^qBK48rL*w@|vhd2&z*Dq6F(T6f<6- z)}pGid|_b?OcQ`C49TyJR)WDokRlK*Hg4BT{EVWig_roPoUuEoxjDGE#nul}TlJ?? z&Tq6fehU8i>ZhePe)=ii6si&YW2KLWM)GN^8l0PW+QJchyTuIm3$U_j0&_Mwn?AuI zRoB4{uDi6#yQioh%gApBM%NLO=JO~iZ8!wDku}^CDVfkqfITyJ+?Jpg*>PUBdj~_; zs{_Z=i73gb%pI^#9nu3Z3> zFe=Og|DsCT7EU{MZDT?XhR9T8lVOrfSm}Qb~0=R3L9D+QRR&gSd)D5ME=nfZeR6ckS z!Bbdk7*4@nG`wvCaQXih(?xe%ZuQ2E* z*4mhOJ?<03C7-OJVnrc5o>mo}68(|#ksWCWfImf3q<}{F(**61sm4<)5IeQg^3YDr zVIs{503*AG9V@?}rXj6NX!YXUog*i+owOrnG)0TAxP-D!;=PIx-XS-|S9uUJRGDZW z^8}JeL*+=^ux4@|x>EYyA%UqmJb_ddg}c~E`K;Ue^EKn+r2E!e`e}<<%tcsvB4FU{ z^b9h>#6M5oJv17IL%=@Wi1{`3JnC^_(G*DV=BEX%EiJH*7B6l^CbN%R(UbubXOImEQ) zT+YJ5Ch}*Q;^o?b7gK791w>!lNHr%*7t)w=pkn3srJ1dD;q&;ugWhF0S#LF$)%a_q zj|&BfP<6`7f8vRGU$CUuQ+h2Wt}r(v;bMQv$oU*gry~oa(yBA2->|L(^fX2SY; zwboB6&3s=({FGuB#qqdVmd+P!t3a686U0`oHTQ@vpMbLF1P38non4jX?Ht@#kXIR; zmuWWqyu0OzxtSPbk1Cb5%Wq2sY-fBwXPLqT>vUl!CV6xdSFB@}LDN)1z_^K1&$$kF z-GN|Tg*7){?}Cu+wJ{J{ujnH`97NyL|3O{mr^%*$=EzrEx(vK|nywkF4>NK|OaAMu zbnJb$fAt)guP&AweUWn)DL=5C|Fh1kpeK;V?g6RdpDkvz>jP%Hn_5L`t87?^R;18(uEwhvkgSj=UaJ12ahwl6rF^Z@53{*k;7cL5e1&5s4xZUqtF=qqOp`q4I zhUQ9_U(5#Hql#BUEps%?8~yDpL^SO1s$Tn<@f%EVG28n?r2c?=vEqbM?QnLx#AY%ql?0uul^IK=GPCwtVt zr(>zNiWQ!-I!4zaidE^c<5JGl=UxBXV?P-xPYBqi<^Uq6$FT2s=Lx3G8)jv)7)>+1 z=xO`iN3$wlXGrj`_y`QEErRnB*h|I@J#lw2}ylnGzmk&Ra)L}5MB*t{z6)6SY zmW$Jt3ukK#!o@+-%s$>3{E=f=JLR`<|7ke_TwDjiSOuADiq$FSI9`CQx&__h989-` zIi%yui6L}CER>>%`)L=xwn>S)e)T9~6IhFdQ*PcVHe^t9Xp$~WxlW(B4iKU$80h4&RqPciOl<-Zl=)IKB^m{7wZh&ff_ZQXl zWaE`2Q1q6p>G)2d4wf_Ic0oibEDHJ%vwtkPNl>l{WsCN>UjC2D59hA|84~|6X!7k1 zkPkpxd7L6)j>J}H-z9c&h)?10h4HX>nGaca@Q83au%0jaickUaetx_d*fD|KekE#0 z4_8VTaOw#b5sRxNCqY{2OQ9o0JNP1IsVYDAoc#IcE;>9xg++1~u~QwK>VctAP~0_U zsNo4KR8imc-Lj{YD+CELM_*1uMHb1?Kjb46mHA)D2^eQ+vtz1_=C7gV6mYp`lba9%H-pKuIFvTvv4pfb*~A2x3*?ko2Ev@^5doMu}?_N$hf^2AdO@jtVG z^iJ!zdsZT51^xOZ_9Ghd`8Rtw4sn!1C@B-h`*rz<4!MbvAoW^A+YWSaz=c*rXI};H zuuh{eo&*>>BtmNRVcDZEsO}A>*qHLoNW_)ZhYLXyAE6^5T6aWzu!$xDuohl3IBZ_V zE@b|24Y1em_8pvv7;kR^wYoJoM@^1FaSJin<#7X?&=_b zqG0#6Y!?r38V}>AV`>|wNET^-|Mc+>u4$&M)WNfY*y5cSa6(j*+>mz@kRv;ZKl44)EzKEz;7kYZ#W< zttwqwy=yOvXb$|$7ES$Kcjz6|ELtzB2POKRsB0C8{!kas4?0W4iI^*I>XtipH@m?` zAl}jyae*vbeYKI}5U8goLOfRrQ~|W*5g=JA21q7$qr;e{zP<4RPARj`r+*p==$jlt zSLjB=(jJ=>BP2cLr2Ou`=s!R^qgK zToT3*FDdyj<_A$~MYg7p4Pn&&`LZ+z-@6c5)M+!^Me~$SkEnUM9lwB$^Jx_!Ey9z6W@YS&O z!K7y8+ot70y$)n_!|p4X$Zf(|wF~iIzTt^%TqRkd;LRKri<(Z?wE|MeoWPqm6v5>m zCd$jqRb`wmd2Km)`o~$&@j+8NH>wn{rkp|A!zjwicpLGj{lc@S?XX5+TL}2Gh(O{_ z-Aq^+w{RJhh z20ERsV8TVT#)~&Wjwj1wRDTFz{*N!IH=qdZIBN?fyO7Q{R-O-DKX)eo}Bu(T9(o z#S$CW8Z&0$S-ZH~c$qB0ip*DsKnck3<#gw`FO*wHzy4nx$G_IJgKr#NiKsMXlrrF>!VeX;apjgi!F2Jr6+6}m&Ty!mb3X^zNEHM!n2Zqy(Wy-xJ_}FX>f9xsTgYA5 zBd~*5v7cl4DRYD^AQk4|V)sOT1zw_v0->p{M{h2&_-Mo5G(vQckDxZd!Rdx z#O73Qq(ANYZ8omuUmifAv)pKMR{HNziOSZ@MN1|AgO;t#+$v>f(G5@Hsy3h8$Ba)YMcfJopf;?)4Sd^knJP z3$3AKz_@dtkO?F_Dewz>fE zqeC3u((9M3;y+%!R6u3N4oSkmX62^|Eh>?~@@z+^O!%g;sAg!&2~X)quF9?61B36J z{#>T+tFzsWWe)Yift2XW$yOx;OCWPId4G|CYAFglPBkaRQq;nONoAri}y3SX*?p8&HJ?{7EQHDXahrD%$Rsyg#=n zEi=wN{}e2YkK`E$V$sjbzf<uat||Rl(0a&x<&1fP zzNw((n!#E!vtC_Dxnn+bLI*bPKf}s5NY)x@oOh~)(QVIj&y>m;cJ1@gr>wAY13pc1 zw{ryod%adXYsGaDoF}8{cUvB0@p1nD4;Nik^(QI0*t5M*{O?RXlTE-E$^Js z<*oiD?49=e)lMZ6IVyYv+UFqbrw!Js89O+%bB6|V+}abXGgI)U9T3F(D1VPQnX1+L z#yv}>TIwCdBEwX$`nL<2qusoLp4Rq)JyL+DDeC8f7)tBzh~n0T;zpg+OPRHd$S}kL zVbP!|q?l5!U{X>|u7xR+Rv=227##`a{&CK87C}Q1YJ)d??sMte>d9yFcpMNGmfx?v zG$37G6ecg&1@|oM!hdk!p?Y|aFqsmk*Y^zyqjSHgU8rp)l*;1@ttfdjnW)qb}y0rdc9lA*5 zq(y)v4J}d))_3lbe~vd+4W3^;F*|Bm7N&JXJ;;QjVdhc~S!nPdY_E||lgvJT{0`lX z?8oXVHYcNa4rd!YgVsS#8KmUbIf#^^8G0lx@g4~g8^-^<0d5J`^(fUj6ziL(J>v_j zpNCcZ1-pc{H+(XdpRQ7%rSwvwq4^PjP_T7F ze#7GFV!VDprEpok$G*Eq9B(=PT3QEx)Lj~a_KYfiH z_w!L$X{MSQhs!&6vK0&yx@nJxDTV_uA=c&CT2K?5 zK>VNpzmk7@#ZN-o$PQbIaQykxxAG8p_F{XDhM(EwQlbI9jcydp%!wdBhD=uT?}-Vu zy({k?TS{w;c(Mm@pXh?lBEt?YUBy#u}D4h(dT6Cj&;51>VPSRGhBRxP!@F!d*fAj3Xq(d~Vb> z%%kSTz0g#Q__P`oi77!o+V z_2dl#8~Iy&@7&K+RH$vC2b+YN(!8fQ-Q8mn_<4}1nMCTwqF=yCW#IQVUQGo(i-8hB60le=BvHL=N#pa zx2J3u_Yd2?kKg(0C#u5O{k}VfOKTOv!cA9yG|!7127Qu?@}nZHvK56+??$!G2(f57y=cJsxr0n4)sqFT2hxWxIGa}q)_VH1p>&x%!%DCjjSA8 zpCeNi)W2kTkMo&|OVWCPFSDDqI>jqKXV0cJikzLi0JC48OE$-r-CF|{xA5jgXbDLm zGVzmDF1_*L7?r$bzBc9%1AcPPO&_V?7{_`Vzv%ZJ2@AVDh;R%p(Gloa(hNzgJ$ks0 z13D38YYn;hcOtzw_qaf8O6NU_7)PVq__XTn75F|5yeWQoDonR5}>|2hi!-1}7dZ9%EHYZ~?oc*-g+KHmB6CZ~2qr&2A*>$y63K|xPeI#>Cy zVL^YzsPoctQQ8+tX<{)5Qci&H$RnDJ##l1A^jg?ovFU3Ats1IHreO8pIXvx8FQAy2 zqct;ULt&Q0Y1xMK%)^4VWff+LUOfgIf?GWOdeh8NsTY4f_aY$x@57<+ub4%c4vf-) zpmGvBsGi4lh_D%~A;(BqrQV;skxoNO3;p05Q4u^i{1x$LhLk-$9SB}byuuR9Xt;2h z%73NtVu<%LhU-Pp=SD9)dx)5PqA;qUVhjCt zj{Mc}CoB++EQHhS;g*{wsb_T}RLxJnqZ3nq5Cfp0<1s0`r}{lmK>_-7>_Oxj`3kn1 zcztmKZ9#ovabTR(*vUI7%N=2b*%8?{>-y9qv;Aw2rXi-L^~b!{UY&yj44Va zb`z)&g%3+P4$-P)#~!B38)&rob&nPbgS?uXo;H)SB%IQ6{!G{9lm-`Fp^GtvgKxCH z5?ZYuwQ}b2LB_~ibjxSydvbV80}h!iU#|~Jad4*#{*;Om6TWzpEMZHJ2HP4T#Bzo7 zdF8(D;vlkO2O+)f1=560M)~}iGfZxGv>r#ogznD*#C!SU!V8v9n(KC51Hq+cSfFnU zF+yzS!g9TCO&>%)oypvtmyZ4rXE{uDKqI(A?m+*-@b25$w{dXPv9x;S@A|$R{Ts>g zr43JTZr9;OYN>NGsl|`jdz%-z5iF1LYjh)KK0o}cLlhCKJj%_cMI8xq_iG{<`CeOH zSG(%kWkPuaFXRUiqCbtoPJbW8@~))d>N_6;g5LF>vGJp>p7gfdg$nLi|6Y{bbTJN$ z%*fg@oTGwHz{sx*qk)|21+U&4Yu`YxJUXz|-2dmc;4XYa&p(lR` zjzfxMD{t?DZAp{h4jPL<2Gt$wdL$t7$<)~#Q$tX0Amtwp$m00HVx}2_w0)WzYFSV? zwrAORtM|+tCIVJjESf6dP2}GPx}mbj7N_Rtn^J2t>^2zfLtqoZdWEpz6T;-I)kY;{ z()F!ne{>FV@{DHk&2zSg<$&&v6d_SRi|~+Ye#k>oM_l2EYkV9^z==UsZVM_l!SzqZ z3?biqIP$iYNaVMjx-E8+GZf_n2Sz&@CW$iNW2?V^Ci4e{--*j&<4c*eH>*9{JS*%w z5}SAW;H5+#=J}1s>}+gN%gX=romkoDZ!C@G9PKX2tYst=ZH|o{T^VE6Ls>UsbE?+_ zg?f($oLAA52k1XBZh#Po*YVAtx~qc{KIOawIEorNG{Sf#u0hT~#XETgA?S^VKUc(; zuR{y155ho6N}9D~{NM76V^TOY=`c-ANZW+Aa?csHd>C9YgbKP-nN3$gm->(`%@xO? z5O!uhMO8$J^@ia5?t04)})ujs^RsNa(d7i$01p z!G&<@tUhR8zxHit6f!L3jboi{g8Nft?YxSn$s~(vUS620wU+(RB1sPx>v4{K13?KA zKUbtT@KaoK3s^fnE?*3WZLp6CXC}Bi`=L@5%|uDPD&tjuClDOMW0Hm8s&y==r5o>2TN88&kr89Do?&S8}e_ z-cbEb7x4?$j_)JXQ|=?v$KJqc&WvZtXaF>(ms9gB%{%5C&E&M{9Nc@?tn#4FhiXDX zXWv3*nMrcnyv|0VTIsi1Q_fT2X_RmFmQo*4?C!fEdQ-m#F(!r{NpN*}fg=eAorlAo zTD{MuJS2GOfLCkJg`e$*^hJG1l1vK3HTKB#uQMxt*mYjQsU8z&!Hk}5bn_OHgf+3NiEYS- zFC?5Kp0!7O;Afk#R_F@S#6B3OTX#{nWB5HE!>sM6qu>rt>AKnKNCwiVCptK1>-7@? zLX^f*O3s&uR#XhQoEITjcg>xYXWoj$-9K}r2fq=|uwr;-tRZIbCRWRQvSrZT-aB({U?9F!0>#x>hBm3>H1L%BO23*jHjDh@u`Q;(H@z2^H5vO}W-; z3jb!p=e~yFsUJYF$KUw6!7lRoy9h-W?R z;G2X7hiopwAktA;^dz z-H?m>x|w+Fi`<^BD>Fo8g{W)}Bj;@k=KVM68ULK?z(#>|FyrJ`5pD`wj&w4&)5QKo)!jvu-7<22HUze4`_oIkhMEB$B4;2GHRu zPG4<$@HnINhBU>G&_;1vAmkP_9BwA8ZQ+&z5(&yp9-#8#;@nOZ`;Rt<2aT+xEFO+0 z-rG~w8yB&S&20B*UNwD(Ud@ZSTw$rATd!Zg04BYO_TZH=vE`a8n0XjBItazRg5vi` z!3J*rM5&F;gmCqa1R*!AD!caU*Vj(j*@;?^vMNzu1}|g^uj#zUQ6;Ye_}RL)&0O(bU;iAg8VT5jSxD>@!>{-Tbr`gB?xqx%4f9{SV80~ zfQs0a(uw#CkuJ3d>p|FilGw6@r7o;QBgZyrh)D2*WWNZJo(H_>sW8h{bmc|lvCrf} z9z|s5C^iF+lE`&-&Y$wj;rPzZBu&zTVcW=ot19NsGdoaW(OYun9NHjO!b8mE&VQ$g zuFtBIJ7UsHs!nogRkb-!X&*QdE!;u!efTqM!J-f?8yo_JcZRYZC)dfC>lwM~W;))C z_Y)!>9Xw32lUWVV(R|NKA+?8p!vfhEpV?@MP(*Yh&h2M-x{TBL#Z=hxYIIk4uNM>| zVBme%LtGt#L?q#azx4jnkO@nb@@}NU+f&wQMFEvGoAop#;=8?Sd92hQSa?5*`ohY+ z2}yt#4PyrzxuWlAL4MF8e?QOzge=g!D~FNrUX%!6=B{*d;Pn}vpOvqZ#tN9Qo=A6L zlLy%7Tew#fozY<+d^%9lc>xn=b^lcSW8L7_8EAkjX2wE=fQcbr+a)|2 zyN`Y|vYTELp;hOinzrFQ-_&^Yu2JNxFs&5FG(*v70^^h>xgdw&^LS=jr&ejyt@hwJ z>@&2CYa-)HV&NYjG%Qmuhgus=>BUX1`Jaj>9pYlm?gi1VCRaYsa?YQgGr4z) z#@HBJDdpWhOtrGcLRN`P=^IEV`0BX<1N=j@EFe0aw*N-9Iyarlwwc%C`?mjm#GJR& zxK5lc7;~?3Q|_?;2iwNVKCww6XFWkbNM_#=B~KL5AL>UW!YsKk`~LLmNqnABsFQU~ zJ_%mZ-Ug4pwKXdvu!=$4k9Na;4FkQc^D=xX|JC{)-u*ZbRQ`@&2Lm*tD9FA{xmSAx zCmuLY?qgW6L?5Hs70h=7pj!pru0UAjoFpZ3H>Mv-K0oXl)3+|H0=wYvVHv4|h28rz ztoaQ#EU*|sd&THs$nzghWv;x9!UJqF9FTJR(ec2Wfb$NJxjA%qwiMNQ3oKrF%$x}| zr?gFV8w|KnY>JYi#;ea8evVe~;k_~-e=}NRQpx~yoIqIT1W9a8*`8n+riBPP7^xezH!$en;X)7@K_7+4r3B;qODPZvwx>Busyfj| z3`U$|3R;wfEOCe_Zo{%LpU0}u30#U@7}o_jBh2GV5T7OZ#^`jB}Mi27KFFIP#lG@1AS2!D>%z{|NsCcOoP7 z7a;PgRg7byPoI42nmQRj!o(p{2tkKK^hreE-+d90i?>!~S}Rfiz2NXg(qU8TGlR06 zf~$`;6{QEU(JleD;0 z8o!65^m$_cmju3d&bY`xM#x>wL6)^Z-J~h41AAgH7 z+MT^3%>S>h_h1}3>stnQot|nW%*zH^s#qF<*INhf;#nU(YK4Slih4$9p+pd!ru%D_ z+f`B90cDf)doQ5*eU(WY57zdHaZl|h-Wp#M6#cYv;SpH8wdBq>M}>$%Rn;te5-zvZ z4pQY7yFJ*?l`KD@_mDDqlW7Ejaw%7n!YTu33Syb&`uFzo7m z*9`>>@u$W=R^+38>u zF0g+zVN=8b!+#@+NsaL~#QdS<8+lu)x0c6(TbIa2_nYjFYT?pMN(Yk@WKi7Xz{Koo ziBy*pa0@u)-JdncyW8Ee(Rj;RGLn*JVAO4MCL<(eW=g5|XoevXV+y=CQVw=1}lUeKM*FfotOE64WtsM z2X?=tSOQ(-M1@M3(ASvSLDSC`LkLwsxdvuD19`~I&aKQ=Rv%{C=AGo10HL24#)ZZh zBDKAERr50hjJAm8A?&sIvZ!`g8CN{b(r#6ANbvhB#$cE?h_1Pb5R4?1}j8JyPDfw?|gwHt8&}9dv9nRMI zRY>8lUmENiY>;UX4&a-G!sg2Vp1j{RlEGTc=o)2k!RmKzbkGPo)rXT^g3I-A91SKZ z(B6vzX!iJSlBE8|N5FYnwz$gPfOoTCGDr7)ru~eml4_ZKr1D&&E>?n)Dl{dZEBc9} zUSnxY|DQWSc(wkGkee)pN6IW;6WUg!`|42OC>-|OM3bo+fpS&RMO%d8>%+80*7~dP z({B^uTkNFg6NcZ=JFrfI31eYEaEKjk>tq$i8JptRxq6xnRmYhIkXpzf~^|fUP>_D7*P$=q4D(Sk-l|nU&3+4+dEeyf> zI#AAOgFEtcqVu0lG=}^&?SEDHB3U}S%iUcl2BnM!D|wC}ZHODQw3xVxuYviX#RpWM zPj(K?`9^6_m&!dn`-)YgQ#$cHhVQN9;s zaPjMh6LJ`3I%5|4igR)mNNXqlg&!6jq!;3Mg=jT^)5^%dUaVZ>=Pfj6F0%RIbp7f$ zfArPzdsmp;R6I6TynTRw7EpRdPlEO)E%`%SMRG=o-OfgWI}FUYU9MxA0C6-H2?WIZv!OJXyM60F}xZyzW_`JY4uZN@+z-;=@dT+P+8+aR)3BwPv&o#Icn?< z@&DpBbzb42V&qA8OMr_nJS9*$=_&cSsv5z-%pL4y%=qT~t^cm!wL_ z54L^g@ll6Gr=j98#~ywC>?QZL-kS=0x4;QcX)EmMojjzw0{G8VeJ8S z>zYIH-U>N{dzg_8RrUUtNtU2*SL`WYz_xJNIWhIQgKuNPU245N-{RcRDFt!T2{gw} zZP2`IDgDB%@q&F2PwloK@RtSLb1&4~m6~7n?+M94fo}MFm_*%Y-k*5a9y=VUSC3#? zNK>p6dAMFTIyxjCZU2bj}hTOO4M#EYg7VVWQ4R){nU z^~wTKN$(3@v+YNqRmQyq-85lP!2|aE(7sK45}b>-->+BfP8utq@@t|u+RF3e|BH0_ zCM)dyLAv(Q@CYHET3Yl(W7#VV>pr`enAxf&%AqALs-QGoVaCs|jJ{*!ca+>uCbxft z{y1f7todNHwaOu9y}5rs>^xM(NbPc@JH)Q9>qlVpf%(iMv+6P2_|1JRUA1&az5&u&d zGTmQ;aTNnl+W4r>x4LIsJPI)(p5Y<9CSIZ}_M+3NXyzmk^nDm`(o(0=p_kFzTw!lB zo$a)^D>Q9GlcC1Glq%)g_3DU@<>M-(Zu?1n;ww)U&|>{SMeMZhOLhT%>gVPHT8d+Z zxv;X9W*5mW9#3k{PuWflT%=&;CWx2S>Vh#i%i9ry{N)ho?SW2a&M6M5Mf=XiKWoF9`K%7whbjq=E-!b|JW{3 z#I266uHB)gB@6d%xC)lDIB!+$pn`Ui3_LKUTuaV z65R`@Jhow7APs%zj`!cZah%aZz$BRG#8<|f-i&XK(Wzl+I08iSi`v;fJ{0wC5NxuB zB&^V;qnDZTIl`3$I+l?Hjz`?W_7c%_Kji(++W6v;U9kbnR;_`uJMDit2X@8Hk2PmG z{c@~a0G73afsCr@U1At@!w_s~$q5BOu!mB_lzV5vPf0#}5eH7a0#6?GnVDk$TH--Q z^Xj{T{@MQnlr^o@-&x0~SsD_e(Mu}YC&X0zVbuMC-8{Yp|EsnCi=HZ&YNWqrK9r2ymamv3x0s2WlMT}j;7yuK!ls@M-F zw*^TmEVp94^!TGWE^vx+B!n{EgYTQIb4(+UjnAYb<`$bJ;NMxQ1xRp}-$$s)vAa4ahNY#a$(Vn8hrByA5-dxb{S z!S4kwQ03FnQa{wPL+so>uHLwvA^i`IwYm18FbKiBXnAh$=j~{f z;gsdQ&_?t+Cqe&V?XT2(IA9K1DH6`5axcqFspheJM9ZE~(U2flj`p(5-}^3#Ht4z} zAIWkgU{w}se1=59A())x$&VPootV*{u*$!qx=*PXebF61hxrHW+K{4|;a{p*vX!hx zxLT3?B`HcRMJ9T-G(_mg}Ef!BXykb%s9BjW^co5Q|Vj_ z)kBfjger{`QC@$1q&O&|N)TM`BsK%A-uiWX_Wg}wq!|}6U|CV_bsMv92fpBz*d8T1 zG|AbL#&au^3rWJPq@t1fDhLRfW>zz02un&|I7gSGH3;M)CBn-~W@ms-FXGv3A<8VJ zKD;2^QjC$up$Yt=oZxRjX|-mj?D?1)e`+YzTtH@({eS24(W3p$oh^TWnDO-Es~`aY zTTYbvMdhGavt=jysOz$UMY$@7&V&!CGbkK5_v--`;Eqa&4bZJKhUqlY$L&6em&#Qy z`1ElWrnp&?x%(L566UVkxB?Vx$athCN~(h%kLi z9);nM-w%p&4G4uQB|26%ft@sk9Vv5smv80qQ(wQqRvfaVo2Yvc^N|A6Q8(G-#@kE2vcq*uEw@AKPRwqOUKTH>X zA%|#W3TrScZ5H~o4~0Hu%Zb&DOXY!nh$G%oS>Gx};_h*m^PGvLMer?nL;i);5Mx_6Pax2-7mc^ZJ2Q1qj5@w z)3bTG+q2sel!9A-L5C5rk0)z`N$hO4GY)i6rxn)+t5HdZjwrfgh_tuT?loVlkBf?#6H|Plu@mY=> zC$f!r+$=`ms81e%3B#hvh^Kku^olJziJ}#V?7pJ4efvcJyh>&JIIFS!GYxv3??B^ zDWD|DYYI;mhwc==jTE!89XJa{+r&%1+}ly(A$`wVu2ztxQkJFL0d#VF!`h!&fPG*+ z4YY1E9*eqFSe5+T*UKk%ZpCtDGbFc2yg`M=aS;RKN&dGf;~p(?6p?i^;vb4(3X)bqHT9GByTpELGH!t#4*g9$2O z0j0Diu~KA@sh_CuRhvcKC1MAA3K7^5^s^D}LLGorm zqJ=UFLl-c_g+=IfBV-!dOCAw*KF0_0G%&S9inr%dJlg34Jehp zuhZd@-~gtXshw0kI0u|f48KKo&usC!zVp&@B0~8LaU5WHQ4+K7Y6Y8y z4)s7kRrmW042~hHu#Cz5<$@a;EP_N!l|I@)>Y`D<2__XYVM zvD#&G)k^L`ul=~S4x)Bt+>XX+ocxQ-X*iXjw_8&Ps5XoYQKjmTR^as}9a-8N|WHzK-#D z@$^=72q8#l^merLQ4EB2>b$xV2LfbA(Ty zAIZexN3T3)gDRGAhA2nTU$AuR=JWvm@~DuWDb+`Kgyu{AfagAzjF;-tYe=;ehIY(@?igOz|x`#bAhDyuu2%b z>5f>YG8`8CA#zcuCLc`e+(4w*DIXyqnYOe6`$u;7ro&<(tehJOfjvJN`<;%QQzbpX z9t&H6r^uVtTC}o(JCDl2LXTa?Qc z0OM)|wh&{$Ep{|{UU4n%JLTc#oR!qcvg5z)yS-yUq zM5+2Rw)Sx%|NN%DJjJZY0u~Ue%ca}5BO#la+9Jx!pB*z)0t4>|N8pr#+IqWhY<8NW;L?LKp+ zJ~F@5i#b#trb9piMyEO7^XoWc_D2F0)IDN%SC6u8JFL^quhen0KaW-y#m0v0a%sfg zbbp1Bj9>+DOom5^V;farv+k3rg~=KXeqe&h>&)1&mK_ez~GiaEf6CT6)~V zg_05yp)KFf5g0bn#ZWviy@#is9p$loMZTaxnJtQ<;{?Js{v;tcc*M^3A>sz)e$qTN zJUo~BLwT3l<)n%ssMUnXh@P2nH8qM%Zz@m*z{+J+g-|EQ16!BC`~|ayryedLb5~99 zrugeYB`}LHSxh(vIIUQB+#pPE&iLuu;-&jfL*=&W(Ta(T-HCiFBB@s&ZRkWKQ-_|? zyj%(En6WJ31Hg7XKh#_O_%Jk}OG6OfIr$*{{h#VEl4EDWFU_p*^8`Y`6RSpA(*Ldv zD#*CVQWkJCA79tlot-ymox@C9fOcvwjUsT!hyh=eK8t5d9z~qTr|b)pHtp}Qy;m9z zScuPs?$5Tna#&T(uZ?xquJ^ofj4+Xru0v*H+R=yoKitTg^zjD}!I_$g9I-sq0g&gg zVQ-08= z;-XMPn0%&@Mn9P@BatL0uh)U4s*_`}UBRbIZ$9K19LQM)e)MsHYVqk!1Ms`i0PDM& z{VTI%niBm%hvL-voN`K}b-MKzD=;}C>Kb7^AF$IF8R&b4Y`fb8 zLD(ld8lOfNnz%C7-TeyZoP7Gl5;`CuP4zZO>_Eu^q~JB}5e&26_`$rADsPq^B9V#b zbe$0YsVEmXeyLjDHc@|kFeLg4{sfJY_xadu$eQaqTrq|oHX%;LVI)^m3~eL~*U-}! zXKh|hL*&2ECyD6Bcbi$hOr0S9ppk6f={HcbTo3L4POfo2u%m{&4{L(pWV*ukQ@J(?_b$a)~4Cy^|ygae0^M|*6sSKjB^^PuQ)5RK#k=OnPVG=Qs z!~T`fh{mLMoVrd)BjrI7kjCDNPX~}PL)X37BbPKU$|Pu{aAj9CyJG@R_s2f4nqd!p zucoa#4pTw4xT5T;*4??(EgxOhmX*UI94;W z^h8YEmWpKq^GTe&9WlV7VeAJ4bly)iVH;95H$CQVd=V{!tC+DwEpyDBHTvPad^`NA zKTQQSkF4TwHQDp0Bf%=PIUxe2rAOt7DbLHM$^OhGwLe+8cEk>mR6slHi-#kNdiZp8 za6T!Uh^eW(MWjWdndSm`oarkHK5gh!-zUWMI3hPusc=U3rji^8jQJ2<*T$AnH)_<; z519GP0FMZ?=G6#=U%wE1G}H5Xm#ACD&Ox`%CGQsToejd6t5egc5(Ef9>@GDX9%wBZ zh@lQ}G=_l<(1))GKcvQnrqh`gl-@cMM99T^d^D;`6MrKCt6;o_jvnT=vmT{yjg_yg zICVatnRJf#gK?em{RhLUDwnbpUB$!5Tcm2z*wnR;8;b_A>2|8%B0T0eI*WLR&xdF@ z0o+Ywrr{`|F;3Llq_e&d0s#x{v5G+GtkT!dQxbs4CA_v(%Ai}MFK0BzZah9B-CZdmli#u)0WxQt7?|X?>Kg^y-d7dgIc^k zSi97vng)~PiMj<8QMLN%I)MHgee_I7T_xkr76ES>ba<4KC z@;jlF5Obf6fRjuGFyrWQ^ivTBv%C+jy5_;yT8iX9)l|B%xtzugX)T-TKb0uhmXiuV zoS^xRjWLI?G39foWuPa6 zK1FRQ>WR}!<`Tzs>8^QD@4LK$WK*fGp3dPDbaZLAtxR)nEkysvNMO=9uA>#$i74xq zea2=ha+cL5aLsoRbOt~{r)H5m9NrwGXW~9h|13(%7tU2QXj$AH6T(pJYyQ((y z0}(vCpUq>z zOKZAq#SUT@+b|^x|4{WM0CAGoC&ST$JzrTIy|aui64l3Ls%2`MAm))?p9fTmcSq9( z_<^=22OWzOLtSzKjF*_grkz^tiC5y~KMDDJMP5_S59xns&foPUppCn@IYOy;=t2ai zRe6H_O@of%eg!k~vXrSb<28UXj)8zt6;<*yuzp9~x%OvjsPZBYdKJ^l<&1=uX!Qk} z6U`WGq)*sUR2|EyP!ab#uvjDRrKPWoR)6ICx>UvRhXIvpOAO0j}F3UKoys>jI-S>6dRm%?Jh8RDq@O8dq9 zS$%}eu5ugwfof@%uxJEs&V{c(=d)!bHuK#Z3mubX*itwK1z`?-iO8LrC{O_qUk`_d zhE$?1;;iYpFeU#v1~o5Jp7emDDk&*7Pi!HI4)v=hmd;D7E*4qw7vZ=l%qNB9gwm)r z!AHT|0-KpG;^wu--P(wUX$0xm1umf-2PCnbzv4=wEulZsN+ihW*a94w=CNi_Pep>> zngHTeo}b|bRe5joDmTR@%>-Ku{;?_K*n}%wWwbvs1EnP=wL3rG3oEUba68dLkQ3qu zCLFUjyV3GvO6K>U-+(rD-ZsEnLBT0M!EFFCau`8$+3?6$HB}FaaiW`)y*kA+X-+KQ zXqB`0H(Qem}r`9 zQ+i&uDYWHu5kE9tHPtuFqUJQ&Yfb8X4(m%UKa~9&I{}63 z^M!h6skeAcNzjM$`r0J}Podv!lh-QztGAaWt``(9scp`KS_D1#Y3~lV)=WUsG46b( z&`ao-^50(jI8f!6$NSYBBtFVMC^c>aoouM3ZtRBi&?xfi)KhjW08wU|EdbbKODiPc z6w|=-Yvks)8C9WgoUHo@hT$+{Hn5PfPrYOGZw6U0U;z0rW^7T0sAZ>#T&{?f9Cm{A zmOi2e)V2A|_zn|K$*Ed=dGZFC%JX-TD8uLRXWbg?!4#s@zk{qqd(majdYr!+oD8ah z<|lrQWq;{P^ihBhz&|M(SP$7ZiG8bbHy&1kuB1zEF*e^*+`sf3TH4E;Rf(o(O%*-9 zq#Bi{P%?w=T}`R0kfHp)^GGIBsl}gpWYYE1`*~=5bLz0c*8bSFsioj}o~`FDKP!wP zPnR?2XJP8dFOcePF5lO1B&esAtEWSaeHhLfkfnyp} zF`9j-gaw?itrmnx=CE#5enR35a=KDj_H{{yx||V+g9z2wNwge@3lftdPr`C^1^6|Z zA5$}uPO$eQ8YPk(PdH#b( zY&gvadrO1_T$0KHN8g<5TI?X=L^4abrhQL0+}%WsjnKrtAGn_crc;plyS|N7=P{dpfD|8vOLzAQ@1= zk;LauN1GTg17lN7WcJQgM5{j$R@?nk{K0^#C(k7P=q<^UJQ_9`cM$qOh1wnZQ$5&CZ$HZ*TeY~0-tS&Tl+mP=!tz@b zHUOC`7Is84&r_1y8V5-%#jK~^cT8bA!HjN%p9RMDs*Ey!3k{#Oy6+zf=@pnmKUC%? zX~Fxqk#Q{-9N9wloVuJepbQm{5<{pU?jI4TM$gC}V%S=%2n`6yf3dX!ZH%%+ta0tf zUrKQG_c}V(SaZzVD3A?bXp~5DQ04Gvy$o?$N}zGqd1&5yFQ`Ib*n7Ki0z2^fa1+0n zw|%Cy&$#$3{PtPZ+r1#FHU*g_>11Ir^&}NXBpO-LxhT4;TYxzX!wg`Kf-a+?q2nNR z=BIDAOejL7aQgKdA+90omXfrUPVU$)wPCl%zHTJk2+{#wXo9b?B65#Z=ojp!*$H6g{eP z6W?7Gk8I57*Nd91)N`H@v2Vv5GD7}YBrP?P!$SR?K?1q`yF@0VciGOb<38a>zjA`v z!}mMVqCi+C4kT%)O{B3Ya#E&nDF`kSdF`wd#20Zo&RwgC+N#DB;C>!9uS+bNvQWN` z{}CSp3aWeRDmb{4d=RK6AXkY-TTLg%s9ty*xpzK7zTGtOI<`$@8hOYqH?%;VDs`DNvlZqmD%q7~ZqZQhd}d>BiCeFEAF{ zb3=y*iu^$m8=WQ{3(=uD1k(okH~C2yksg-W;?}k%rB3Eq`#8-Mwh%bvM=ctgYTqSX zl)hz{oWwPslxL!!05J*KyC67-?vIT7(7C6RpV_pWw3h=Lnug!f-NFK=;p*R~P}A5L z$YVd|EN*7)%15N@#m%Ky9sOd^?F=_i`FQ>y8?iO zIO1Fi@9XF3!yLX_N2)&h3`KSr&xp+?uTY~PRYQ0=l{1;J=zSC_#FbC%~Q0z`rQB9%OS+Sr3O1lkt2Kfo-`VK$r74+7%B0mSanRO6T%brwKeq+9jg_W-d!{7|N7)jQEH=FgF@~UTVe-+>}v;D-KDjv2Z^d|p} z&^W!>c-3x6W#|147>bs}=KB!<^$zQ0T(I{XKS-Ff_?5XE=rA>pq{008kD@krX zBUqSn-+;TL%D!a?29u1&uhoN>WRS#!kl!_ZNqpMwcIJ$;t&=9kq=ohP#;5>5MyH~3 z*T#CHBNP5uj&eg!#3Ss0G_!Mk-+ zFVFo+mxKV+Qfyo5mCmscxI+^xUw$#T--eETz> zl@i{lpF3GnD~(%de?i}ub6{Z?kvXmUr$ULu)?S$WA9bVaG^kLUD|vj_~jCW-6d#dri;`Jl(B zEi3!xg=w1)yvM7HYDNE&%qv@gq>u0c z^-+pmt6a^Dr5|w_lNMcB9l2iV+Q}3YQS!EM3V$4rECxBD%~q@zLaz)-M(Hr-URE33 z>HoEsiH4}*%ToLr60&VZJ$-@N4Suoi(AAg~(8o`r=mycc@pJ8XlvJO4{8Jlfbd+D9 zI0UXmNWSM*t*lceY99ojqM&%OxFBb_&`sjRoV23SFqorobh?xm5GJN`8JA1=De4Uu_ ztHp-5M`|sFTN$&O?g{;ic-urGHy0xg-FldzW|-LB^w`G8fwrAx&!3zPgw|y0L+U9M z-o$r1NG37G?qnk+RdCqcg}RkdE{Aot?doieU46LrWTV89NBttGOp2q4mSv!1ZFj$k z+h8)ux&W4qc!9Yc4=n-4n^)s1jxGLG%|f>+QV}>XuG)$ueOjvef5sXwF5wEk7)ZI!-%$FmBY@cXTpBFdy4$K7O8O^P_&g!wM_0TKur{)G||? z@?RtPb}|O*Q7BL~D%(n;)!(c3Fv;RJk>d1Jt{sYd6TRV~_||3yFLI5?Lo5r(Xc z2IM5y(>g*{PT@bX_nM69!tthNjWm^WOxyZ4D(Z6xXDD9~0DX^;)z=mY7tOoE!cd+Y zG|So^Edv+2Me^p&8*Q1ZY8v~v&r&Sd@EErkC-r%yb}D`kIrm3OF%WdFop^N;Wa?LC z#~su-y>`ZgRXAtzrmDV0sm^Z(taK92pE z!0#`Wq7PMs>KD>xflR?oXg3s~7Pya4nxSF_4YX*ND#o{H}F0hbU&w8_| zml&#tdJOKf{(3kw=>K}dX?s$;DPHY9P9-ldVmJ{Jnz0v1^bX=dQU8Uo zVYu?khh4kXy@u=5ihkW#&D1!n`?{;2=oJLZkaL7gji~?*c*I^sLdR&jb3PdK{2oZK z)j8h8%X5c6_J+lo1$Kj-v zr1AZm^i;RO@ckt|q(m%KGHPButNpFYu&@BN!v4j-*(fM_Lljnmzw7k=0=Qb-Yigc; zlYBS2z^aS0v9%fDeOJ|0!kgfoAL3E zCcVyo&?0z?1W>s6aiw|Dj`%{uFp#k)QX^+DvWq{E)fl8kiu`7;0wOaZpVt#Rn7L)1qP<*}h7%RfB!U!8w$RcMfQefoi-oV$%tgkXYKyVsCpf#m76 z)^s$Ib2AX-Yq2=H@oG*>793IYHj@5X=>F@((5}rx}s5J z9OR0&6AiWmSOy0605U~4O5u;#8bf?)Di$v&#Db}H z438Mwi>J3Mg-%mHLALz81I(k=hobpFu zIL3Vev_zI>*a^@WI1D}+LUj#}$jE+|KCTF>GpW&@{xVm;PO>G6fa(xVQ@wq+glg*B z5Rlo%urhPSqzs3D1->Hx0O~C?k}BXIVQ&Xs=9Is1s2YR1pc2^)C^pwe zG)Z+*|4Yf$Y>Zz`%^?wBt91J^mu5^l6;yvIfH6)d<^FY(`H;YC{4UCRG8t+3m_)>V zE&cCBd4ghFgtZq}YQ0P*z2X^4zh@u~fU(G8|sl#$r}GtzqyMLfi_2P{912hQkYh~$EdcP6xnLuf4 zL7+twY9(CLj`?quVaN_x5Gd_;In<@!V7=6U;>>FsNrC@nbkp0JEl@eFAk(9WAi5V%YP`o2%B7iQNY=T#~wv@ zf!I-DOkA!)R3$5w1a?^U(GVW((9Vkq2yzSg;5qVfI(&BAiCd3VB?u`rK#5YkYAGL` z!MM{VQa}+rm{tYhC$gqJENJM}JWNHSyCHC>hj;}H~%et{mRoNGO%Cdd+}uQmi@ zAx!DtVLiLpA=t*KX?+l`Fx4=BYA@4Wrv3x*{?ydp++BT%mQWd82xt%l0OV!oZefEQF&KLZYhk%LzbjstVR_iWrG)G3oxDgdw{zYwJ zo03u?2|9KKh+i=}!=ErA*2qM}4vSB|#sg~&_H{j3Pr}8WD;#Y%q32bj1Whe|H0?n| z?z}y`S)QjacrOigXQ)fxCl@`9ylGy+FHe;-N{0jP$oIG!&b7LY>>fgCra{!6x_hC` zRn0KhFz7C$wDjLy=HG@Mr-X|B>-}qpRrQ01Cw!-eZ?gkuSN{|u7;`zO5=fgz8y@7T zQsEsWsX5|H-aGPe648{ zHxmm>Hb>Q?SQ8W4Yyok^Aw3B;Y)p#;Ww)A>PLheugo~J=&lX8dnloZnw6bFrMs%Ug zH#*%@#&;p2X`sXwW~l+Vfv>`u+@JK&k=(?oQr}K9o4>q%Qw5(>02RL>nN#q*5B&{g z4_}G`)x6T*sGdZ6g((fxw@jIVJ~GwDl6*s@xpG#BDB zjB{LDHG$aqe0$V1SK=o#DS{)dk=iVKYmtxn_%{W{~8(3lY65r}MT#$SD~ zH@V-#v#Lp*BBy<14zzayS{-0gyrr?ZI}9Co4d3hFdQm^Ik$U&|oSZM{*+xuy?g1Z| zqpt8As4yT&3j4XgK`y!fh@3!?i|d2G&9XfHSvA=ShQ5w7t@4Na2BuYKI*F#B0ah6& z%he^M3OK6oC{?tQQiwk_851o8LYM~?06eU;vngqACbVH-<~(>QSY#eK3BcE%#Hwhp z-(w>ArV!@y#Zj#v2eY^#Y@~F2$=ZShttc*|%`2okh|^C4@)Y-BN~zTPt4(Cz*^bU2 zGQJ3LJ%mhtN1b0J;ssES*jtuhU)WadFrFbH=akC4bswnhPo6sXxGchK;_)wyc)Mu9 z&OzoH*W3m4=~ZF5pd3^Y19YCAe@c-;D%`=Vus@}!rAoD-gWjKb)aHY1Q6$n0?C0!F zTZ-6{Vx&uS;qH5`aAn z5fS~0s_o~YC z%;XH*NSi(dq*w|@{F^%Mq>&01K+1gO2a{aH+f-=cN1?Gxfddt0z_;2VqW2%KZ-+zA zt#vfyVRvFPnAy)UVkA_BNZ=db0f?Q5B_e7abvDDS3}$8+!WI{{gZ#CHkD+l1%^a}k z>4#;|qY2Y6)UJC(Nh+U?=Ic%W3Acr=Jh884JX`2be8vij3U@-tDhkEvCw*_eaqoct z*MtydjP@v8K(EK3Q?w=#EQZbFUC#|>6T14amQ(09{hOH1^2;ptX0`A8*kC#y3bAEF z0O+Cq`&Rp=!Szmn8k>Iv_WRp|2-q0@24=%>#3xmCVOxU8wGxi%Y16cHzS>2{T|FIN zH~&n4T=H@NA9@!V6HN%392{YBdKlvpOLd)C|3N=57HHw0*w@k9-kJMIn72_Jpco1|~!-=o0 zvKEQsYtqmp5SR8!tv>_GgM|7_8pN?iF;kNMlJz=snQ8&|A#(y>rVVub{hQTKbdjSz zf$dE5;1MmOb`JGdJC#!uU>-ll)#gMxTeg-)E9q@i_#$|8Vi$jb6py$(~IT`7{Rk;7A zw|z9l`O74F?XJM!;N1#=3fHd=)9JJ~zYEv9%8m5jxW}tj(EeRLc81*8SZxfxS$u+K zZlaq@=e;E>&M;~!kdcfR==uAieQc~ioHmq@n5tx5MSL~=T2`OhKk?H>tv8e%`J8*B zjLY&kfhg>7!o)@+s3wNvcmm#Qs?!&#IMfez05bp zNJOpqY3D06e+C-~9=zuiUM}mMDl>nVA%)3S`U$5SE67$69tOY!gVVAVh|xU)RWSuf z!<|9X8B#;j={A4?sE|TIrmh_8ALF?g2@6kMV2f#Lm>|IpV)Q!?0^CM#D7Z>1%eGD- zPXGJRWN7e(7_@+!#BIx*BDSN$4vps`Pxwc}mL;LS9g2?tqUVSLTKG=S(?S7@x?U*e zgQO-JpjKyj=YXMz^6h&kE97=MgQIeoPI=G5)lKflVD5x#b=7%LGIj#&EKZ}w69aq! z@=_3Th>afCUNrtPrz=m`Nz73vp36@LwF2-MGV4jY^?6|3%NX~J2PV5dTBL$64Bl;} zU(B_4$ME6d$WiHDlssJr0zg_CG`94+>}qz9D#>X;5CHSjb`?9*!8;B=vnHxZW=7t) zbKX)kLTxPaMtb4k!+1V^%aPJ>To+ihR?GFt3kWy*TRa0 zdO07mGOy?h5YSyqB{@#QX;G==OiBs7(K7B%MH{|sr}D+nlXoSGyB#Uta~nz1^9uC? zz!&VsHWxI*>I;FT`mC6AOGIhhiad`!{DHl|Ni-;9clsdQ*!Jg#)=?jrLed8tOPs== z$Qs{qsXx*(WtyYO7$%L31W0@3SijROdbK{BY82puvU9v5{(4Ze+Io;YVhwdlVKyB> zz)S#e`#KWR>!)e{jv(pW`|9GM=QS7g8W+y;5H^Ku^A4Akv$8=yvSM=fd*7PErR|h4 zJ2M^WIkFzCu%L@Zacg%9vCjU3sbNR<=r7ja^d`kKeEHIi8iPl-%2HmHO(;S<8mQjq zRVYJVs6`xzYNT=#yto=$6&3rM)wXdn8i&96ClwXGW$i5ktFfA@KFxRoAVSv7VGG|p=7`Rw5wZhEGcFl3uA_Ed4!>>kBRe8nENiPVV$^3rjrWroT*S7 zahCHMTY)Z<)&jc=@O*dK057#pgk*;568O9KUTtuYvEXOo+v}y{l9B5`8?y)@(Ihl- z)=WRoBc*t6SNihH2-nONi^ZwBYpvjXy=LU6A6I)(cmG8w{@lJmg&-HZs#Jbw3O@*8 zGGXv~!v(neLaP`%2Wk7tIxNYb;Z{^G