Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
2faaf76
separate out TokenController upgrade.
danoctavian Jan 6, 2023
98dc7b5
enable relevant tests for rewards
danoctavian Jan 10, 2023
888884d
fix get-legacy-assessment-rewards.js to write file correctly
danoctavian Jan 11, 2023
2cc314a
update transfer values
danoctavian Jan 11, 2023
b7cd82f
temp debug setup
danoctavian Jan 11, 2023
ecdd33b
fix TokenController memory layout
danoctavian Jan 12, 2023
4bd815f
fix tc.operatorTransfer
danoctavian Jan 12, 2023
8ba7b7a
remove tc.initialize
danoctavian Jan 12, 2023
5716932
print out balance of TokenController
danoctavian Jan 16, 2023
355caaa
add aggregation of governance rewards + balance in TC
danoctavian Jan 17, 2023
89f09a5
update eligibleForCLAUnlock to latest data set. update migration-v2 t…
danoctavian Jan 17, 2023
0c0cf09
fix position stakingPoolNXMBalances
danoctavian Jan 17, 2023
6b69740
add withdawable cover note script. (slow)
danoctavian Jan 18, 2023
fda8277
add script for fetching withdrawable cover note amount
danoctavian Jan 18, 2023
3066602
add latest version for pre-computing total locked per user using on-c…
danoctavian Jan 18, 2023
ca35af2
move computation for total rewards earlier in the flow (no network I/O)
danoctavian Jan 18, 2023
bfc13fd
add unlockeable tokens measurement
danoctavian Jan 18, 2023
58d5acb
add batch procession for CA removal
danoctavian Jan 18, 2023
2f1d453
make cleaned up version of fork test
danoctavian Jan 19, 2023
0aee37b
fix lint
danoctavian Jan 19, 2023
a48c2ee
fix lint
danoctavian Jan 19, 2023
3ba0ead
add newly generated file for addresses eligible for conver note withd…
danoctavian Jan 19, 2023
3d66b82
add addresses rewardable for governance
danoctavian Jan 19, 2023
ca540cc
fix pool val assert
danoctavian Jan 19, 2023
a0c8b46
fix TC upgrade in the first upgrade stage
danoctavian Jan 19, 2023
305bbe6
disable check for now for gov rewards
danoctavian Jan 19, 2023
0b543a9
Use cache in governance rewards and withdrawable cover notes scripts
shark0der Jan 20, 2023
9bcc758
fix WETH address
danoctavian Jan 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions contracts/modules/governance/NXMaster.sol
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ contract NXMaster is INXMMaster {
) external onlyAuthorizedToGovern {
require(newContractCodes.length == newAddresses.length, "NXMaster: newContractCodes.length != newAddresses.length.");
require(newContractCodes.length == _types.length, "NXMaster: newContractCodes.length != _types.length");

for (uint i = 0; i < newContractCodes.length; i++) {
addNewInternalContract(newContractCodes[i], newAddresses[i], _types[i]);
}
Expand Down Expand Up @@ -95,6 +96,7 @@ contract NXMaster is INXMMaster {
} else if (_type == uint(ContractType.Proxy)) {

newInternalContract = payable(new OwnedUpgradeabilityProxy(contractAddress));

isProxy[contractCode] = true;
} else {
revert("NXMaster: Unsupported contract type");
Expand Down
23 changes: 18 additions & 5 deletions contracts/modules/legacy/LegacyClaimsReward.sol
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@ contract LegacyClaimsReward is ILegacyClaimsReward, LegacyMasterAware {

function transferRewards() override external {
// REWARD_TRANSFERS_HELPER_BEGIN
tk.transfer(0x8D38C81B7bE9Dbe7440D66B92d4EF529806baAE7, 35760493284880538281);
tk.transfer(0x87B2a7559d85f4653f13E6546A14189cd5455d45, 55352901017354677134);
tk.transfer(0x8D38C81B7bE9Dbe7440D66B92d4EF529806baAE7, 44711571167651250552);
tk.transfer(0x87B2a7559d85f4653f13E6546A14189cd5455d45, 129028627954719654319);
tk.transfer(0xb7FeE4f0e877A348481355FFf757D8A079A2A48b, 833640762734095);
tk.transfer(0xe5DD78C224F26E306c84A9B1aa2DEF30bdf15835, 4244323033916347);
tk.transfer(0xF9fA438fE4723C9B2096868F892c1C5F14bb2cAa, 255737891525236889);
Expand All @@ -59,7 +59,6 @@ contract LegacyClaimsReward is ILegacyClaimsReward, LegacyMasterAware {
tk.transfer(0x927165752a4dDF685F9D6eF21Fd180b0f9Bc7E03, 269639440705719);
tk.transfer(0x21Cf5649ee1a9362202EBfF266Ef7BBC8c26A917, 116286322435811720);
tk.transfer(0x76FE8E056230344B65104ca3c96FF062bFAf9cf7, 292661475471199774);
tk.transfer(0x0A8C2eE08760251705f5aaF7bb0E7B490029Bc27, 292164303519382683);
tk.transfer(0x57F589DcBd0fd14b4528018f8Ba6777696D38ECD, 195857733291784);
tk.transfer(0xCb95cAB0D557808491A0d498aCaE4fb37277da00, 797989782506267);
tk.transfer(0xB791CE850C29732D7F8116d813457c840040102b, 151075450744570);
Expand All @@ -75,14 +74,28 @@ contract LegacyClaimsReward is ILegacyClaimsReward, LegacyMasterAware {
tk.transfer(0xa13eF1eB4f6603321f05a95C0E8bb2c847FFe5a2, 1292070249286796);
tk.transfer(0x0616e02d2492e33ABa850b9a83cFd379169c00be, 4734737571918997);
tk.transfer(0x7f8069Dfdd61f3AaAbDFf9F6D7257496733D340d, 2474823651144190);
tk.transfer(0x92A0b2C089733beF43Ac367D2CE7783526AEA590, 7860439097919);
tk.transfer(0xbee0889F9f74090889C3AD5fDf174b6Af6480607, 31441756391679);
tk.transfer(0x4c262bA680b20640a51d00a7D2D3115a54A04108, 5242073859524);
tk.transfer(0x07cD0dffB4ca317c56c232A8130a7c3f07BF207A, 92726739727973018);
tk.transfer(0xF99b3a13d46A04735BF3828eB3030cfED5Ea0087, 4752837513833318820);
tk.transfer(0xe497145776d5A8d8fD101aBc070371a4eaDcdD1a, 52704844647291947);
tk.transfer(0xa7009b120eb1016A91a9aCEC52D243BEf01de74e, 10651502465310038504);
tk.transfer(0xf76e252e3c40EEF8A90a4fcD1a34ee8209115074, 210504943489815226);
tk.transfer(0x2255B4523939045C6F4C42fD0b6d945C52bE98A8, 102063437327263615);
tk.transfer(0xF7e5Ac6564105980d1c1ECd7a3b4C5a8bAe9982E, 446637592594148042);
tk.transfer(0x585013080dc32E4a3790aaA95702619eC5eB6C07, 27225854970139123);
tk.transfer(0xD816a5Fb7c78282f7880173d1bb8A18EF00E5D0D, 945086714857539398);
tk.transfer(0x53e60bb4603950377Ea15b268b5741143369952F, 88259315016974844);
tk.transfer(0x10cCD4136471c7c266a9Fc4569622989Fb4caB99, 30734263435297258);
tk.transfer(0x3fb751Cbc56275AE92288D758750493c9159a070, 257096803157521);
tk.transfer(0xF1f756AafaB77Ef2fec51b567Df1e23332F4ac78, 5919598866587998699);
tk.transfer(0x4334703B0B74E2045926f82F4158A103fCE1Df4f, 2236979868823378247);
tk.transfer(0x5fA07227d05774C2ff11c2425919d14225a38DBB, 63405006681877230);
tk.transfer(0x6852C2Ac09CcB4B7Cd39BAB7e5427f48d8265da0, 5547886985344996295);
tk.transfer(0x5929cC4D10b6a1acc5bF5D221889f10251C628A1, 24072809369912029);
tk.transfer(0xaA0D63A8303873Bc4569F810aFc1C3475279739A, 2036528796472687);
tk.transfer(0x546a0cB802377153B4fEAe052a5ed14C98B3CC9C, 100206484380862328);
tk.transfer(0xC3774aF3452628636D031544D1e8893c3D8701AB, 2043870268022841232);
tk.transfer(0xe201fC1Da79E71b953C07a1A24F5Ad3c974F2813, 865876463648643);
// REWARD_TRANSFERS_HELPER_END

uint remainderNMX = tk.balanceOf(address(this));
Expand Down
15 changes: 9 additions & 6 deletions contracts/modules/token/TokenController.sol
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,17 @@ import "./external/LockHandler.sol";
contract TokenController is ITokenController, LockHandler, MasterAwareV2 {
using SafeUintCast for uint;

address public _unused0;
address public _unused1;
address public _unused2;
address public _unused3;
address public _unused4;
address public _unused_token;
address public _unused_pooledStaking;
address public _unused_minCALockTime;
address public _unused_claimSubmissionGracePeriod;

mapping(uint => StakingPoolNXMBalances) public override stakingPoolNXMBalances;

// coverId => CoverInfo
mapping(uint => CoverInfo) public override coverInfo;


IQuotationData public immutable quotationData;
address public immutable claimsReward;
address public immutable stakingPoolFactory;
Expand Down Expand Up @@ -101,9 +101,12 @@ contract TokenController is ITokenController, LockHandler, MasterAwareV2 {
address _to,
uint _value
) external override onlyInternal returns (bool) {

INXMToken _token = token();
_token.operatorTransfer(_from, _value);
_token.transfer(_to, _value);
if (_to != address(this)) {
_token.transfer(_to, _value);
}
return true;
}

Expand Down
41 changes: 29 additions & 12 deletions scripts/get-governance-rewards.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
require('dotenv').config();
const { ethers, config } = require('hardhat');
const fs = require('fs');
const ethers = require('ethers');
const path = require('path');
const fetch = require('node-fetch');

const VERSION_DATA_URL = 'https://api.nexusmutual.io/version-data/data.json';

const { PROVIDER_URL } = process.env;

const EVENTS_START_BLOCK = 0;
const OUTPUT_FILE = path.join(
config.paths.root,
'scripts/v2-migration/output', // dir
'governance-rewardable.json', // filename
);

const getContractFactory = async providerOrSigner => {
const data = await fetch(VERSION_DATA_URL).then(r => r.json());
Expand All @@ -25,8 +27,13 @@ function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}

const main = async () => {
const provider = new ethers.providers.JsonRpcProvider(PROVIDER_URL);
const main = async (provider, useCache = true) => {
// check the cache first
if (useCache && fs.existsSync(OUTPUT_FILE)) {
console.log('Using cached data for goverance rewards');
return JSON.parse(fs.readFileSync(OUTPUT_FILE).toString());
}

const factory = await getContractFactory(provider);
const governance = await factory('GV');

Expand All @@ -42,6 +49,9 @@ const main = async () => {
})
.filter(onlyUnique);

console.log(`Fetched ${addresses.length} addresses.`);

console.log(`Fetching getPendingReward for each..`);
const rewards = await Promise.all(addresses.map(address => governance.getPendingReward(address)));

const rewardable = addresses.reduce((acc, address, index) => {
Expand All @@ -55,10 +65,17 @@ const main = async () => {
console.log(rewardable);
console.log(Object.keys(rewardable).length);

fs.appendFileSync('governance-rewardable.json', JSON.stringify(rewardable, null, 2), 'utf8');
fs.appendFileSync(OUTPUT_FILE, JSON.stringify(rewardable, null, 2), 'utf8');
};

main().catch(e => {
console.log('Unhandled error encountered: ', e.stack);
process.exit(1);
});
if (require.main === module) {
// use default provider and bypass cache when run via cli
main(ethers.provider, false)
.then(() => process.exit(0))
.catch(e => {
console.log('Unhandled error encountered: ', e.stack);
process.exit(1);
});
}

module.exports = main;
14 changes: 10 additions & 4 deletions scripts/get-legacy-assessment-rewards.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ function onlyUnique(value, index, self) {
return self.indexOf(value) === index;
}

const getTransferCalls = rewardable => {
const transfers = Object.keys(rewardable).map(address => `tk.transfer(${address}, ${rewardable[address]});`);
const getTransferCalls = rewardables => {
const transfers = rewardables.map(rewardable => `tk.transfer(${rewardable.address}, ${rewardable.reward});`);

const items = ['// REWARD_TRANSFERS_HELPER_BEGIN', ...transfers, '// REWARD_TRANSFERS_HELPER_END'];

Expand All @@ -38,6 +38,7 @@ const main = async provider => {
const claimRewards = await factory('CR');

const contractPath = path.join(__dirname, '../contracts/modules/legacy/LegacyClaimsReward.sol');

const contract = fs.readFileSync(contractPath).toString();

console.log('Collecting vote events');
Expand All @@ -59,16 +60,21 @@ const main = async provider => {
const rewards = await Promise.all(addresses.map(address => claimRewards.getRewardToBeDistributedByUser(address)));
console.log('Rewards fetched');

const rewardable = addresses.map((address, i) => ({ address, reward: rewards[i].toString() }));
const rewardable = addresses
.map((address, i) => ({ address, reward: rewards[i].toString() }))
.filter(rewardable => rewardable.reward !== '0');

const rewardablePath = path.join(__dirname, 'rewardable.json');
fs.writeFileSync(rewardablePath, JSON.stringify(rewardable, null, 2), 'utf8');

// Regex used to replace the transfer operations in LegacyClaimsReward.sol
const templateHelperRegex = / +\/\/ REWARD_TRANSFERS_HELPER_BEGIN.*\/\/ REWARD_TRANSFERS_HELPER_END/;
const templateHelperRegex = / +\/\/ REWARD_TRANSFERS_HELPER_BEGIN.*\/\/ REWARD_TRANSFERS_HELPER_END/s;

const transferCalls = getTransferCalls(rewardable);

const newContract = contract.replace(templateHelperRegex, transferCalls);

console.log(`Write new contract to path ${contractPath}`);
fs.writeFileSync(contractPath, newContract);
};

Expand Down
7 changes: 6 additions & 1 deletion scripts/get-locked-in-v1-claim-assessment.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ async function getMemberStake(i, mr, tc) {
return { member, amount: '0' };
}

const amount = await tc.tokensLocked(member, ethers.utils.formatBytes32String('CLA'));
const tokensLockedAmount = await tc.tokensLocked(member, ethers.utils.formatBytes32String('CLA'));

const tokensUnlockable = await tc.tokensUnlockable(member, ethers.utils.formatBytes32String('CLA'));

// Add both locked and unlockeable
const amount = tokensLockedAmount.add(tokensUnlockable);

return { member, amount: amount.toString() };
}
Expand Down
86 changes: 86 additions & 0 deletions scripts/get-withdrawable-cover-notes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
const { ethers, config } = require('hardhat');
const fs = require('fs');
const path = require('path');
const fetch = require('node-fetch');

const VERSION_DATA_URL = 'https://api.nexusmutual.io/version-data/data.json';
const OUTPUT_FILE = path.join(
config.paths.root,
'scripts/v2-migration/output', // dir
'eligible-for-cover-note-withdraw.json', // filename
);

const getContractFactory = async providerOrSigner => {
const data = await fetch(VERSION_DATA_URL).then(r => r.json());
const abis = data.mainnet.abis
.map(item => ({ ...item, abi: JSON.parse(item.contractAbi) }))
.reduce((data, item) => ({ ...data, [item.code]: item }), {});

return async code => {
const { abi, address } = abis[code];
return new ethers.Contract(address, abi, providerOrSigner);
};
};

const ROLE_MEMBER = 2;

async function getWithdrawableCoverNotes(i, qt, mr) {
const { 0: member, 1: active } = await mr.memberAtIndex(ROLE_MEMBER, i);

if (!active) {
return { member, withdrawableAmount: '0' };
}

const withdrawableAmount = await qt.getWithdrawableCoverNotesAmount(member);
return {
withdrawableAmount: withdrawableAmount.toString(),
member,
};
}

async function main(provider, useCache = true) {
// check the cache first
if (useCache && fs.existsSync(OUTPUT_FILE)) {
console.log('Using cached data for withdrawable cover notes');
return JSON.parse(fs.readFileSync(OUTPUT_FILE).toString());
}

const factory = await getContractFactory(provider);
const mr = await factory('MR');
const qt = await factory('QT');

const memberCount = (await mr.membersLength(ROLE_MEMBER)).toNumber();
const memberIds = [...Array(memberCount).keys()];
const memberWithdrawableCoverNotes = [];

console.log('Fetching claim assessment stakes...');

while (memberIds.length > 0) {
const batch = memberIds.splice(0, 200);
const withdrawableCoverNotes = await Promise.all(
batch.map(async i => {
const withdrawableAmountWithMember = await getWithdrawableCoverNotes(i, qt, mr);
return withdrawableAmountWithMember;
}),
);
memberWithdrawableCoverNotes.push(...withdrawableCoverNotes);
console.log(`Processed ${memberWithdrawableCoverNotes.length}/${memberCount}`);
}

const nonZeroMemberWithdrawableCoverNotes = memberWithdrawableCoverNotes.filter(x => x.withdrawableAmount !== '0');

fs.writeFileSync(OUTPUT_FILE, JSON.stringify(nonZeroMemberWithdrawableCoverNotes, null, 2));

return nonZeroMemberWithdrawableCoverNotes;
}

if (require.main === module) {
main(ethers.provider, false)
.then(() => process.exit(0))
.catch(e => {
console.log('Unhandled error encountered: ', e.stack);
process.exit(1);
});
}

module.exports = main;
Loading