diff --git a/.openzeppelin/rinkeby.json b/.openzeppelin/rinkeby.json index 502e38a..51d37b3 100644 --- a/.openzeppelin/rinkeby.json +++ b/.openzeppelin/rinkeby.json @@ -5265,11 +5265,11 @@ } }, "VaultSavingsModule": { - "address": "0x70F8F75E344bF1b181631F61A5242010ec974910", - "constructorCode": "6080604052614e85806100136000396000f3fe", - "bodyBytecodeHash": "063d748f70995f9896947d7592eb61e37b7ee9a78dc31b86d89be55134aae074", - "localBytecodeHash": "e407e3dad2b60da79b7c218e64072d2f43b53c72fca8ae49e01b2efcf9054eac", - "deployedBytecodeHash": "e407e3dad2b60da79b7c218e64072d2f43b53c72fca8ae49e01b2efcf9054eac", + "address": "0x50663d45722aD4E085419D8fdA6e0db0f110A201", + "constructorCode": "6080604052614dc1806100136000396000f3fe", + "bodyBytecodeHash": "cd67bbf96862c79f371377f73b5e4963cea7fa7907ed00992642b9e9071021b5", + "localBytecodeHash": "c051fe5294ff6a5eef02cded539584b2a6adaddded5ceeac4b088af012f510f8", + "deployedBytecodeHash": "c051fe5294ff6a5eef02cded539584b2a6adaddded5ceeac4b088af012f510f8", "types": { "t_bool": { "id": "t_bool", @@ -5300,25 +5300,25 @@ "members": [ { "label": "poolToken", - "astId": 17205, + "astId": 17357, "type": "t_address", "src": "562:17:87" }, { "label": "totalShares", - "astId": 17207, + "astId": 17359, "type": "t_uint256", "src": "653:19:87" }, { "label": "rewardTokens", - "astId": 17210, + "astId": 17362, "type": "t_array:dyn", "src": "761:22:87" }, { "label": "amounts", - "astId": 17214, + "astId": 17366, "type": "t_mapping", "src": "849:33:87" } @@ -5351,19 +5351,19 @@ "members": [ { "label": "nextDistribution", - "astId": 17222, + "astId": 17374, "type": "t_uint256", "src": "1071:24:87" }, { "label": "shares", - "astId": 17226, + "astId": 17378, "type": "t_mapping", "src": "1105:34:87" }, { "label": "rewardsByProtocol", - "astId": 17230, + "astId": 17382, "type": "t_mapping>", "src": "1227:57:87" } @@ -5376,7 +5376,7 @@ "members": [ { "label": "amounts", - "astId": 17219, + "astId": 17371, "type": "t_mapping", "src": "933:33:87" } @@ -5401,9 +5401,9 @@ "members": [ { "label": "bearer", - "astId": 34271, + "astId": 35799, "type": "t_mapping", - "src": "150:32:125" + "src": "150:32:130" } ] }, @@ -5420,13 +5420,13 @@ "members": [ { "label": "userCap", - "astId": 17448, + "astId": 17600, "type": "t_mapping", "src": "1253:35:88" }, { "label": "isVipUser", - "astId": 17452, + "astId": 17604, "type": "t_mapping", "src": "1367:32:88" } @@ -5445,13 +5445,13 @@ "members": [ { "label": "poolToken", - "astId": 19456, + "astId": 19854, "type": "t_address", "src": "917:24:91" }, { "label": "previousBalance", - "astId": 19458, + "astId": 19856, "type": "t_uint256", "src": "951:23:91" } @@ -5475,41 +5475,41 @@ "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "initialized", - "astId": 36341, + "astId": 37869, "type": "t_bool", - "src": "757:24:142" + "src": "757:24:147" }, { "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "initializing", - "astId": 36343, + "astId": 37871, "type": "t_bool", - "src": "876:25:142" + "src": "876:25:147" }, { "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "______gap", - "astId": 36405, + "astId": 37933, "type": "t_array:50", - "src": "1982:29:142" + "src": "1982:29:147" }, { "contract": "Ownable", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\ownership\\Ownable.sol", "label": "_owner", - "astId": 35274, + "astId": 36802, "type": "t_address", - "src": "526:22:133" + "src": "526:22:138" }, { "contract": "Ownable", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\ownership\\Ownable.sol", "label": "______gap", - "astId": 35387, + "astId": 36915, "type": "t_array:50", - "src": "2471:29:133" + "src": "2471:29:138" }, { "contract": "Module", @@ -5523,7 +5523,7 @@ "contract": "RewardDistributions", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\RewardDistributions.sol", "label": "rewardDistributions", - "astId": 17234, + "astId": 17386, "type": "t_array:dyn>", "src": "1382:45:87" }, @@ -5531,7 +5531,7 @@ "contract": "RewardDistributions", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\RewardDistributions.sol", "label": "rewardBalances", - "astId": 17238, + "astId": 17390, "type": "t_mapping>", "src": "1433:46:87" }, @@ -5539,23 +5539,23 @@ "contract": "CapperRole", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\access\\roles\\CapperRole.sol", "label": "_cappers", - "astId": 34368, + "astId": 35896, "type": "t_struct", - "src": "327:27:126" + "src": "327:27:131" }, { "contract": "CapperRole", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\access\\roles\\CapperRole.sol", "label": "______gap", - "astId": 34468, + "astId": 35996, "type": "t_array:50", - "src": "1193:29:126" + "src": "1193:29:131" }, { "contract": "SavingsCap", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\SavingsCap.sol", "label": "protocolsCapInfo", - "astId": 17457, + "astId": 17609, "type": "t_mapping>", "src": "1419:52:88" }, @@ -5563,7 +5563,7 @@ "contract": "SavingsCap", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\SavingsCap.sol", "label": "userCapEnabled", - "astId": 17459, + "astId": 17611, "type": "t_bool", "src": "1554:26:88" }, @@ -5571,7 +5571,7 @@ "contract": "SavingsCap", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\SavingsCap.sol", "label": "protocolCapEnabled", - "astId": 17461, + "astId": 17613, "type": "t_bool", "src": "1586:30:88" }, @@ -5579,7 +5579,7 @@ "contract": "SavingsCap", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\SavingsCap.sol", "label": "defaultUserCap", - "astId": 17465, + "astId": 17617, "type": "t_mapping", "src": "1622:47:88" }, @@ -5587,7 +5587,7 @@ "contract": "SavingsCap", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\SavingsCap.sol", "label": "protocolCap", - "astId": 17469, + "astId": 17621, "type": "t_mapping", "src": "1675:44:88" }, @@ -5595,7 +5595,7 @@ "contract": "SavingsCap", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\SavingsCap.sol", "label": "vipUserEnabled", - "astId": 17471, + "astId": 17623, "type": "t_bool", "src": "1725:26:88" }, @@ -5603,7 +5603,7 @@ "contract": "VaultOperatorRole", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\VaultOperatorRole.sol", "label": "_managers", - "astId": 19319, + "astId": 19717, "type": "t_struct", "src": "448:28:90" }, @@ -5611,7 +5611,7 @@ "contract": "VaultSavingsModule", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\VaultSavingsModule.sol", "label": "registeredVaults", - "astId": 19462, + "astId": 19860, "type": "t_array:dyn", "src": "987:35:91" }, @@ -5619,7 +5619,7 @@ "contract": "VaultSavingsModule", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\VaultSavingsModule.sol", "label": "vaults", - "astId": 19466, + "astId": 19864, "type": "t_mapping>", "src": "1028:36:91" }, @@ -5627,7 +5627,7 @@ "contract": "VaultSavingsModule", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\VaultSavingsModule.sol", "label": "poolTokenToVault", - "astId": 19470, + "astId": 19868, "type": "t_mapping", "src": "1070:44:91" } @@ -5643,7 +5643,7 @@ "contract": "RewardDistributions", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\RewardDistributions.sol", "label": "rewardDistributions", - "astId": 17234, + "astId": 17386, "type": "t_array:dyn>", "src": "1382:45:87" }, @@ -5651,7 +5651,7 @@ "contract": "RewardDistributions", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\RewardDistributions.sol", "label": "rewardBalances", - "astId": 17238, + "astId": 17390, "type": "t_mapping>", "src": "1433:46:87" }, @@ -5659,15 +5659,15 @@ "contract": "CapperRole", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\access\\roles\\CapperRole.sol", "label": "_cappers", - "astId": 34368, + "astId": 35896, "type": "t_struct", - "src": "327:27:126" + "src": "327:27:131" }, { "contract": "SavingsCap", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\SavingsCap.sol", "label": "protocolsCapInfo", - "astId": 17457, + "astId": 17609, "type": "t_mapping>", "src": "1419:52:88" }, @@ -5675,7 +5675,7 @@ "contract": "VaultOperatorRole", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\VaultOperatorRole.sol", "label": "_managers", - "astId": 19319, + "astId": 19717, "type": "t_struct", "src": "448:28:90" }, @@ -5683,7 +5683,7 @@ "contract": "VaultSavingsModule", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\savings\\VaultSavingsModule.sol", "label": "vaults", - "astId": 19466, + "astId": 19864, "type": "t_mapping>", "src": "1028:36:91" } @@ -5692,11 +5692,11 @@ } }, "CurveFiStablecoinStrategy": { - "address": "0x94A65aca64D8eD76B5643730D4802c36f9178B55", - "constructorCode": "608060405261433c806100136000396000f3fe", - "bodyBytecodeHash": "18ee8cfad8a7993bdff70245a4c4b8d7a2f041860d0c22bfebef1ec13efb658b", - "localBytecodeHash": "551334178569b0980ce42843479dd74dc6c4ac2cbeac6f3c1750d1f4027582ea", - "deployedBytecodeHash": "551334178569b0980ce42843479dd74dc6c4ac2cbeac6f3c1750d1f4027582ea", + "address": "0xE472bBD1E3C8Dc8A9194bf0bb88D43D6bFea08A3", + "constructorCode": "60806040526146d8806100136000396000f3fe", + "bodyBytecodeHash": "188ba324fac25c05dd449deb847e11d0610af8344a27e0184af3f5c6507eb3b8", + "localBytecodeHash": "6a8d0f4e721c3e4ad7d8b785aaa9374db662a6c17b7054271a4821d1e304ef13", + "deployedBytecodeHash": "6a8d0f4e721c3e4ad7d8b785aaa9374db662a6c17b7054271a4821d1e304ef13", "types": { "t_bool": { "id": "t_bool", @@ -5727,9 +5727,9 @@ "members": [ { "label": "bearer", - "astId": 34271, + "astId": 35799, "type": "t_mapping", - "src": "150:32:125" + "src": "150:32:130" } ] }, @@ -5775,41 +5775,41 @@ "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "initialized", - "astId": 36341, + "astId": 37869, "type": "t_bool", - "src": "757:24:142" + "src": "757:24:147" }, { "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "initializing", - "astId": 36343, + "astId": 37871, "type": "t_bool", - "src": "876:25:142" + "src": "876:25:147" }, { "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "______gap", - "astId": 36405, + "astId": 37933, "type": "t_array:50", - "src": "1982:29:142" + "src": "1982:29:147" }, { "contract": "Ownable", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\ownership\\Ownable.sol", "label": "_owner", - "astId": 35274, + "astId": 36802, "type": "t_address", - "src": "526:22:133" + "src": "526:22:138" }, { "contract": "Ownable", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\ownership\\Ownable.sol", "label": "______gap", - "astId": 35387, + "astId": 36915, "type": "t_array:50", - "src": "2471:29:133" + "src": "2471:29:138" }, { "contract": "Module", @@ -5823,7 +5823,7 @@ "contract": "DefiOperatorRole", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\DefiOperatorRole.sol", "label": "_operators", - "astId": 9389, + "astId": 9478, "type": "t_struct", "src": "445:29:79" }, @@ -5935,7 +5935,7 @@ "contract": "DefiOperatorRole", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\DefiOperatorRole.sol", "label": "_operators", - "astId": 9389, + "astId": 9478, "type": "t_struct", "src": "445:29:79" }, @@ -5952,11 +5952,11 @@ } }, "PoolToken_Vault_CurveFi": { - "address": "0x811ef08973E8cBEcff90353a796BF5DabF8cA026", - "constructorCode": "6080604052613559806100136000396000f3fe", - "bodyBytecodeHash": "9f69ad5883accb0b9b6a630000e67cf0030e2574d3ead956a22f0a5f4b36d200", - "localBytecodeHash": "280a1edfcc653a971e7d28079a6b2656c4c65cef433cb880224985710d444fa1", - "deployedBytecodeHash": "280a1edfcc653a971e7d28079a6b2656c4c65cef433cb880224985710d444fa1", + "address": "0x3b5BB186f6AACe78de622999efFfd6a479f2Ff94", + "constructorCode": "60806040526135cb806100136000396000f3fe", + "bodyBytecodeHash": "7ac00afaaaa3c539fd8b7c2515f5e97501c54bf68a13d69d6c0aae835b22554d", + "localBytecodeHash": "bd7b355eeaf8517a9bab158e118876c46e87cb20ac6f5a3907b380dd7d0683d3", + "deployedBytecodeHash": "bd7b355eeaf8517a9bab158e118876c46e87cb20ac6f5a3907b380dd7d0683d3", "types": { "t_bool": { "id": "t_bool", @@ -6003,9 +6003,9 @@ "members": [ { "label": "bearer", - "astId": 33518, + "astId": 35799, "type": "t_mapping", - "src": "150:32:123" + "src": "150:32:130" } ] }, @@ -6022,15 +6022,15 @@ "members": [ { "label": "amount", - "astId": 22130, + "astId": 22946, "type": "t_uint256", - "src": "745:14:95" + "src": "745:14:96" }, { "label": "totalSupply", - "astId": 22132, + "astId": 22948, "type": "t_uint256", - "src": "832:19:95" + "src": "832:19:96" } ] }, @@ -6047,41 +6047,41 @@ "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "initialized", - "astId": 35588, + "astId": 37869, "type": "t_bool", - "src": "757:24:140" + "src": "757:24:147" }, { "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "initializing", - "astId": 35590, + "astId": 37871, "type": "t_bool", - "src": "876:25:140" + "src": "876:25:147" }, { "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "______gap", - "astId": 35652, + "astId": 37933, "type": "t_array:50", - "src": "1982:29:140" + "src": "1982:29:147" }, { "contract": "Ownable", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\ownership\\Ownable.sol", "label": "_owner", - "astId": 34521, + "astId": 36802, "type": "t_address", - "src": "526:22:131" + "src": "526:22:138" }, { "contract": "Ownable", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\ownership\\Ownable.sol", "label": "______gap", - "astId": 34634, + "astId": 36915, "type": "t_array:50", - "src": "2471:29:131" + "src": "2471:29:138" }, { "contract": "Module", @@ -6095,161 +6095,161 @@ "contract": "ERC20", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\token\\ERC20\\ERC20.sol", "label": "_balances", - "astId": 34654, + "astId": 36935, "type": "t_mapping", - "src": "1418:46:132" + "src": "1418:46:139" }, { "contract": "ERC20", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\token\\ERC20\\ERC20.sol", "label": "_allowances", - "astId": 34660, + "astId": 36941, "type": "t_mapping", - "src": "1471:69:132" + "src": "1471:69:139" }, { "contract": "ERC20", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\token\\ERC20\\ERC20.sol", "label": "_totalSupply", - "astId": 34662, + "astId": 36943, "type": "t_uint256", - "src": "1547:28:132" + "src": "1547:28:139" }, { "contract": "ERC20", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\token\\ERC20\\ERC20.sol", "label": "______gap", - "astId": 35046, + "astId": 37327, "type": "t_array:50", - "src": "8172:29:132" + "src": "8172:29:139" }, { "contract": "ERC20Detailed", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\token\\ERC20\\ERC20Detailed.sol", "label": "_name", - "astId": 35098, + "astId": 37379, "type": "t_string", - "src": "224:20:134" + "src": "224:20:141" }, { "contract": "ERC20Detailed", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\token\\ERC20\\ERC20Detailed.sol", "label": "_symbol", - "astId": 35100, + "astId": 37381, "type": "t_string", - "src": "250:22:134" + "src": "250:22:141" }, { "contract": "ERC20Detailed", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\token\\ERC20\\ERC20Detailed.sol", "label": "_decimals", - "astId": 35102, + "astId": 37383, "type": "t_uint8", - "src": "278:23:134" + "src": "278:23:141" }, { "contract": "ERC20Detailed", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\token\\ERC20\\ERC20Detailed.sol", "label": "______gap", - "astId": 35154, + "astId": 37435, "type": "t_array:50", - "src": "1654:29:134" + "src": "1654:29:141" }, { "contract": "MinterRole", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\access\\roles\\MinterRole.sol", "label": "_minters", - "astId": 33738, + "astId": 36019, "type": "t_struct", - "src": "327:27:125" + "src": "327:27:132" }, { "contract": "MinterRole", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\access\\roles\\MinterRole.sol", "label": "______gap", - "astId": 33838, + "astId": 36119, "type": "t_array:50", - "src": "1193:29:125" + "src": "1193:29:132" }, { "contract": "ERC20Mintable", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\token\\ERC20\\ERC20Mintable.sol", "label": "______gap", - "astId": 35203, + "astId": 37484, "type": "t_array:50", - "src": "831:29:135" + "src": "831:29:142" }, { "contract": "ERC20Burnable", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\token\\ERC20\\ERC20Burnable.sol", "label": "______gap", - "astId": 35087, + "astId": 37368, "type": "t_array:50", - "src": "761:29:133" + "src": "761:29:140" }, { "contract": "DistributionToken", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\token\\DistributionToken.sol", "label": "distributions", - "astId": 22136, + "astId": 22952, "type": "t_array:dyn>", - "src": "903:35:95" + "src": "903:35:96" }, { "contract": "DistributionToken", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\token\\DistributionToken.sol", "label": "nextDistributions", - "astId": 22140, + "astId": 22956, "type": "t_mapping", - "src": "992:52:95" + "src": "992:52:96" }, { "contract": "DistributionToken", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\token\\DistributionToken.sol", "label": "nextDistributionTimestamp", - "astId": 22142, + "astId": 22958, "type": "t_uint256", - "src": "1107:40:95" + "src": "1107:40:96" }, { "contract": "DistributionToken", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\token\\DistributionToken.sol", "label": "distributionAccumulator", - "astId": 22144, + "astId": 22960, "type": "t_uint256", - "src": "1242:38:95" - }, - { - "contract": "DistributionToken", - "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\token\\DistributionToken.sol", - "label": "toBeMinted", - "astId": 22146, - "type": "t_uint256", - "src": "1337:27:95" + "src": "1242:38:96" }, { "contract": "PoolToken", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\token\\PoolToken.sol", "label": "allowTransfers", - "astId": 22846, + "astId": 23652, "type": "t_bool", - "src": "628:19:96" + "src": "628:19:97" + }, + { + "contract": "VaultPoolToken", + "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\token\\VaultPoolToken.sol", + "label": "toBeMinted", + "astId": 23809, + "type": "t_uint256", + "src": "165:27:98" }, { "contract": "VaultPoolToken", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\token\\VaultPoolToken.sol", "label": "onHoldAmount", - "astId": 23022, + "astId": 23813, "type": "t_mapping", - "src": "165:49:97" + "src": "199:49:98" }, { "contract": "VaultPoolToken", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\token\\VaultPoolToken.sol", "label": "totalOnHold", - "astId": 23024, + "astId": 23815, "type": "t_uint256", - "src": "220:19:97" + "src": "254:19:98" } ], "warnings": { @@ -6263,28 +6263,28 @@ "contract": "MinterRole", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\access\\roles\\MinterRole.sol", "label": "_minters", - "astId": 33738, + "astId": 36019, "type": "t_struct", - "src": "327:27:125" + "src": "327:27:132" }, { "contract": "DistributionToken", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\token\\DistributionToken.sol", "label": "distributions", - "astId": 22136, + "astId": 22952, "type": "t_array:dyn>", - "src": "903:35:95" + "src": "903:35:96" } ], "storageDiff": [] } }, "VaultProtocolCurveFi": { - "address": "0x08643acF34D41D7aDB980f39b4bD459C8Ab3dfB1", - "constructorCode": "60806040526153d0806100136000396000f3fe", - "bodyBytecodeHash": "a14b5565c1821066e91b79b0a396a4d6c4767495ba45f228dbe4f8a68551e94f", - "localBytecodeHash": "9a2cc79e6a0c7f8b3207b7024913280af3f66ddb84e748bbc2222e9599fcf418", - "deployedBytecodeHash": "9a2cc79e6a0c7f8b3207b7024913280af3f66ddb84e748bbc2222e9599fcf418", + "address": "0xb60e66857133e30eba21638aa3114Bf6510a3B69", + "constructorCode": "60806040526158d4806100136000396000f3fe", + "bodyBytecodeHash": "aed5f2de4e5735faa4df4df70c2c805bc23730a9534f81e68faead1da156eca1", + "localBytecodeHash": "32f377f42715a552f730001dee530fa4c253fe5098735253e68674ed726ff4e8", + "deployedBytecodeHash": "32f377f42715a552f730001dee530fa4c253fe5098735253e68674ed726ff4e8", "types": { "t_bool": { "id": "t_bool", @@ -6315,9 +6315,9 @@ "members": [ { "label": "bearer", - "astId": 33922, + "astId": 35799, "type": "t_mapping", - "src": "150:32:124" + "src": "150:32:130" } ] }, @@ -6353,41 +6353,41 @@ "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "initialized", - "astId": 35992, + "astId": 37869, "type": "t_bool", - "src": "757:24:141" + "src": "757:24:147" }, { "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "initializing", - "astId": 35994, + "astId": 37871, "type": "t_bool", - "src": "876:25:141" + "src": "876:25:147" }, { "contract": "Initializable", "path": "@openzeppelin\\upgrades\\contracts\\Initializable.sol", "label": "______gap", - "astId": 36056, + "astId": 37933, "type": "t_array:50", - "src": "1982:29:141" + "src": "1982:29:147" }, { "contract": "Ownable", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\ownership\\Ownable.sol", "label": "_owner", - "astId": 34925, + "astId": 36802, "type": "t_address", - "src": "526:22:132" + "src": "526:22:138" }, { "contract": "Ownable", "path": "@openzeppelin\\contracts-ethereum-package\\contracts\\ownership\\Ownable.sol", "label": "______gap", - "astId": 35038, + "astId": 36915, "type": "t_array:50", - "src": "2471:29:132" + "src": "2471:29:138" }, { "contract": "Module", @@ -6401,7 +6401,7 @@ "contract": "DefiOperatorRole", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\DefiOperatorRole.sol", "label": "_operators", - "astId": 9365, + "astId": 9478, "type": "t_struct", "src": "445:29:79" }, @@ -6409,7 +6409,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "strategies", - "astId": 10509, + "astId": 10622, "type": "t_array:dyn", "src": "726:29:82" }, @@ -6417,7 +6417,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "registeredVaultTokens", - "astId": 10512, + "astId": 10625, "type": "t_array:dyn", "src": "761:40:82" }, @@ -6425,7 +6425,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "balancesOnHold", - "astId": 10517, + "astId": 10630, "type": "t_mapping>", "src": "863:53:82" }, @@ -6433,7 +6433,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "usersDeposited", - "astId": 10520, + "astId": 10633, "type": "t_array:dyn", "src": "922:33:82" }, @@ -6441,7 +6441,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "lastProcessedDeposits", - "astId": 10523, + "astId": 10636, "type": "t_array:dyn", "src": "990:31:82" }, @@ -6449,7 +6449,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "balancesRequested", - "astId": 10528, + "astId": 10641, "type": "t_mapping>", "src": "1092:56:82" }, @@ -6457,7 +6457,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "usersRequested", - "astId": 10531, + "astId": 10644, "type": "t_array:dyn", "src": "1154:33:82" }, @@ -6465,7 +6465,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "lastProcessedRequests", - "astId": 10534, + "astId": 10647, "type": "t_array:dyn", "src": "1222:31:82" }, @@ -6473,7 +6473,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "balancesToClaim", - "astId": 10539, + "astId": 10652, "type": "t_mapping>", "src": "1260:54:82" }, @@ -6481,7 +6481,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "claimableTokens", - "astId": 10542, + "astId": 10655, "type": "t_array:dyn", "src": "1320:34:82" }, @@ -6489,7 +6489,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "quickStrategy", - "astId": 10544, + "astId": 10657, "type": "t_address", "src": "1361:28:82" }, @@ -6497,7 +6497,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "availableEnabled", - "astId": 10546, + "astId": 10659, "type": "t_bool", "src": "1435:30:82" }, @@ -6505,7 +6505,7 @@ "contract": "VaultProtocol", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\VaultProtocol.sol", "label": "remainders", - "astId": 10549, + "astId": 10662, "type": "t_array:dyn", "src": "1471:29:82" } @@ -6521,14 +6521,14 @@ "contract": "DefiOperatorRole", "path": "..\\..\\..\\D\\projects\\akropolis\\savings-pool\\contracts\\modules\\defi\\DefiOperatorRole.sol", "label": "_operators", - "astId": 9365, + "astId": 9478, "type": "t_struct", "src": "445:29:79" } ], "storageDiff": [] } - } + } }, "solidityLibs": {}, "proxies": { @@ -6696,36 +6696,36 @@ ], "akropolis-savings-pool/VaultSavingsModule": [ { - "address": "0x172cd550d0E08AcB67f6C4712bC9F78a99FCa83D", + "address": "0xA0ce47C8072C0eAA5d0E343b7aE533e0E377c0F7", "version": "1.0.0", - "implementation": "0x70F8F75E344bF1b181631F61A5242010ec974910", + "implementation": "0x50663d45722aD4E085419D8fdA6e0db0f110A201", "admin": "0x7B27e0dAED14F0DFA17aa8a23f39c5dbF6FaAF12", "kind": "Upgradeable" } ], "akropolis-savings-pool/VaultProtocolCurveFi": [ { - "address": "0xF0b0d7078bE36a05864Cc9af8EeC9C8232177ec2", + "address": "0x181A9a2bC318F1748437089c1Fc7543e449B99B4", "version": "1.0.0", - "implementation": "0x08643acF34D41D7aDB980f39b4bD459C8Ab3dfB1", + "implementation": "0xb60e66857133e30eba21638aa3114Bf6510a3B69", "admin": "0x7B27e0dAED14F0DFA17aa8a23f39c5dbF6FaAF12", "kind": "Upgradeable" } ], "akropolis-savings-pool/CurveFiStablecoinStrategy": [ { - "address": "0xa79Fc0367e7aA6CeE680284d7e78bA872205b073", + "address": "0x6cd11F017015475Ff08f3e547a45f99AE15081c9", "version": "1.0.0", - "implementation": "0x94A65aca64D8eD76B5643730D4802c36f9178B55", + "implementation": "0xE472bBD1E3C8Dc8A9194bf0bb88D43D6bFea08A3", "admin": "0x7B27e0dAED14F0DFA17aa8a23f39c5dbF6FaAF12", "kind": "Upgradeable" } ], "akropolis-savings-pool/PoolToken_Vault_CurveFi": [ { - "address": "0xb33b69481544573F2f7032a9613b15f998525f5c", + "address": "0x6D205cf0d2A71F687AE727c17768703a9c7A7ADD", "version": "1.0.0", - "implementation": "0x811ef08973E8cBEcff90353a796BF5DabF8cA026", + "implementation": "0x3b5BB186f6AACe78de622999efFfd6a479f2Ff94", "admin": "0x7B27e0dAED14F0DFA17aa8a23f39c5dbF6FaAF12", "kind": "Upgradeable" } diff --git a/abi/CurveFiStablecoinNoDexag.json b/abi/CurveFiStablecoinNoDexag.json index 87c0202..91c7371 100644 --- a/abi/CurveFiStablecoinNoDexag.json +++ b/abi/CurveFiStablecoinNoDexag.json @@ -508,6 +508,21 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_dexagProxy", + "type": "address" + } + ], + "name": "setDexagProxy", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": false, "inputs": [ diff --git a/abi/CurveFiStablecoinStrategy.json b/abi/CurveFiStablecoinStrategy.json index 08a4185..9403889 100644 --- a/abi/CurveFiStablecoinStrategy.json +++ b/abi/CurveFiStablecoinStrategy.json @@ -387,8 +387,13 @@ "inputs": [ { "internalType": "address", - "name": "sender", + "name": "_pool", "type": "address" + }, + { + "internalType": "string", + "name": "_strategyId", + "type": "string" } ], "name": "initialize", @@ -411,13 +416,8 @@ "inputs": [ { "internalType": "address", - "name": "_pool", + "name": "sender", "type": "address" - }, - { - "internalType": "string", - "name": "_strategyId", - "type": "string" } ], "name": "initialize", @@ -471,6 +471,21 @@ "stateMutability": "nonpayable", "type": "function" }, + { + "constant": false, + "inputs": [ + { + "internalType": "address", + "name": "_dexagProxy", + "type": "address" + } + ], + "name": "setDexagProxy", + "outputs": [], + "payable": false, + "stateMutability": "nonpayable", + "type": "function" + }, { "constant": false, "inputs": [ @@ -520,14 +535,9 @@ "type": "address" }, { - "internalType": "address", - "name": "token", - "type": "address" - }, - { - "internalType": "uint256", - "name": "amount", - "type": "uint256" + "internalType": "uint256[]", + "name": "amounts", + "type": "uint256[]" } ], "name": "withdraw", @@ -545,9 +555,14 @@ "type": "address" }, { - "internalType": "uint256[]", - "name": "amounts", - "type": "uint256[]" + "internalType": "address", + "name": "token", + "type": "address" + }, + { + "internalType": "uint256", + "name": "amount", + "type": "uint256" } ], "name": "withdraw", diff --git a/abi/PoolToken.json b/abi/PoolToken.json index 4ae3d6e..3d98cb5 100644 --- a/abi/PoolToken.json +++ b/abi/PoolToken.json @@ -502,6 +502,21 @@ "stateMutability": "view", "type": "function" }, + { + "constant": true, + "inputs": [], + "name": "distributionTotalSupply", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "payable": false, + "stateMutability": "view", + "type": "function" + }, { "constant": true, "inputs": [ @@ -1018,20 +1033,5 @@ "payable": false, "stateMutability": "view", "type": "function" - }, - { - "constant": true, - "inputs": [], - "name": "distributionTotalSupply", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "payable": false, - "stateMutability": "view", - "type": "function" } ] \ No newline at end of file diff --git a/contracts/modules/token/DistributionToken.sol b/contracts/modules/token/DistributionToken.sol index 61c9dbd..b31f03e 100644 --- a/contracts/modules/token/DistributionToken.sol +++ b/contracts/modules/token/DistributionToken.sol @@ -160,8 +160,8 @@ contract DistributionToken is ERC20, ERC20Mintable { uint256 fromDistribution = nextDistributions[account]; if (fromDistribution >= toDistribution) return 0; uint256 distributionAmount = calculateClaimAmount(account, toDistribution); - if (distributionAmount == 0) return 0; nextDistributions[account] = toDistribution; + if (distributionAmount == 0) return 0; super._transfer(address(this), account, distributionAmount); emit DistributionsClaimed(account, distributionAmount, fromDistribution, toDistribution); return distributionAmount; diff --git a/contracts/modules/token/PoolToken.sol b/contracts/modules/token/PoolToken.sol index 1bd2d4a..004f2e0 100644 --- a/contracts/modules/token/PoolToken.sol +++ b/contracts/modules/token/PoolToken.sol @@ -51,9 +51,4 @@ contract PoolToken is Module, ERC20, ERC20Detailed, ERC20Mintable, ERC20Burnable function distributionBalanceOf(address account) public view returns(uint256) { return (account == address(this))?0:super.distributionBalanceOf(account); } - - function distributionTotalSupply() public view returns(uint256) { - return super.distributionTotalSupply().sub(balanceOf(address(this))); - } - } \ No newline at end of file diff --git a/contracts/modules/token/VaultPoolToken.sol b/contracts/modules/token/VaultPoolToken.sol index aa03189..e21dae4 100644 --- a/contracts/modules/token/VaultPoolToken.sol +++ b/contracts/modules/token/VaultPoolToken.sol @@ -20,6 +20,7 @@ contract VaultPoolToken is PoolToken, IOperableToken { } function increaseOnHoldValue(address _user, uint256 _amount) public onlyMinter { + _updateUserBalance(_user); onHoldAmount[_user] = onHoldAmount[_user].add(_amount); totalOnHold = totalOnHold.add(_amount); } @@ -36,6 +37,9 @@ contract VaultPoolToken is PoolToken, IOperableToken { userBalanceChanged(_user); } + else { + revert("Incorrect on hold amount"); + } } function onHoldBalanceOf(address _user) public view returns (uint256) { @@ -50,6 +54,8 @@ contract VaultPoolToken is PoolToken, IOperableToken { } function distributionBalanceOf(address account) public view returns(uint256) { + if (account == address(this)) return 0; + if (balanceOf(account).add(toBeMinted) <= onHoldAmount[account]) return 0; return balanceOf(account).add(toBeMinted).sub(onHoldAmount[account]); diff --git a/deployment_rinkeby.md b/deployment_rinkeby.md index 722bfa0..5cda900 100644 --- a/deployment_rinkeby.md +++ b/deployment_rinkeby.md @@ -71,10 +71,10 @@ * RewardVestingModule `0x214eAB7667848ec753A50Bf98416a8E12D3516f2` * RewardDistributionModule `0x586C698698f316D9f10332A4300859DD8A82B130` -* VaultSavingsModule `0x172cd550d0E08AcB67f6C4712bC9F78a99FCa83D` -* VaultProtocol Curve `0xF0b0d7078bE36a05864Cc9af8EeC9C8232177ec2` -* CurveFiStablecoinStrategy `0xa79Fc0367e7aA6CeE680284d7e78bA872205b073` -* PoolToken for CurveFiStablecoinStrategy `0xb33b69481544573F2f7032a9613b15f998525f5c` +* VaultSavingsModule `0xA0ce47C8072C0eAA5d0E343b7aE533e0E377c0F7` +* VaultProtocol Curve `0x181A9a2bC318F1748437089c1Fc7543e449B99B4` +* CurveFiStablecoinStrategy `0x6cd11F017015475Ff08f3e547a45f99AE15081c9` +* PoolToken for CurveFiStablecoinStrategy `0x6D205cf0d2A71F687AE727c17768703a9c7A7ADD` #### Protocols ##### Curve.Fi Y [(y)DAI, (y)USDC, (y)USDT, (y)TUSD] - YFI diff --git a/scripts/deploy_rinkeby_vault.bat b/scripts/deploy_rinkeby_vault.bat index 480060b..2cc8f2d 100644 --- a/scripts/deploy_rinkeby_vault.bat +++ b/scripts/deploy_rinkeby_vault.bat @@ -23,13 +23,14 @@ rem ==== Akropolis ==== SET MODULE_POOL=0x6CEEd89849f5890392D7c2Ecb429888e2123E99b SET MODULE_ACCESS=0xbFC891b6c83b36aFC9493957065D304661c4189A -SET MODULE_VAULT_SAVINGS=0x172cd550d0E08AcB67f6C4712bC9F78a99FCa83D -SET VAULT_PROTOCOL_CURVE=0xF0b0d7078bE36a05864Cc9af8EeC9C8232177ec2 -SET STRATEGY_CURVE=0xa79Fc0367e7aA6CeE680284d7e78bA872205b073 -SET POOL_TOKEN_VAULT_CURVE=0xb33b69481544573F2f7032a9613b15f998525f5c +SET MODULE_VAULT_SAVINGS=0xA0ce47C8072C0eAA5d0E343b7aE533e0E377c0F7 +SET VAULT_PROTOCOL_CURVE=0x181A9a2bC318F1748437089c1Fc7543e449B99B4 +SET STRATEGY_CURVE=0x6cd11F017015475Ff08f3e547a45f99AE15081c9 +SET POOL_TOKEN_VAULT_CURVE=0x6D205cf0d2A71F687AE727c17768703a9c7A7ADD rem ==== Roles ==== -SET VAULT_OPERATOR=0x5D507818B52A891fe296463adC01EeD9C51e218b +SET VAULT_OPERATOR_01=0x5D507818B52A891fe296463adC01EeD9C51e218b +SET VAULT_OPERATOR_02=0x98f0D2dDB5262202E95666e646775FcC773B8C02 rem === GOTO REQUESTED OP=== @@ -66,7 +67,9 @@ call npx oz send-tx --to %MODULE_VAULT_SAVINGS% --network rinkeby --method setVa goto :done :setupOperator -call npx oz send-tx --to %MODULE_VAULT_SAVINGS% --network rinkeby --method addVaultOperator --args %VAULT_OPERATOR% +call npx oz send-tx --to %MODULE_VAULT_SAVINGS% --network rinkeby --method addVaultOperator --args %VAULT_OPERATOR_01% +call npx oz send-tx --to %MODULE_VAULT_SAVINGS% --network rinkeby --method addVaultOperator --args %VAULT_OPERATOR_02% +call npx oz send-tx --to %POOL_TOKEN_VAULT_CURVE% --network rinkeby --method addMinter --args %VAULT_OPERATOR_02% rem call npx oz send-tx --to %STRATEGY_CURVE% --network rinkeby --method addDefiOperator --args %VAULT_OPERATOR% goto :done diff --git a/test/modules/savings/VaultSavings.ts b/test/modules/savings/VaultSavings.ts index edb3603..afb9e0e 100644 --- a/test/modules/savings/VaultSavings.ts +++ b/test/modules/savings/VaultSavings.ts @@ -921,6 +921,8 @@ contract('VaultSavings', async([ _, owner, user1, user2, user3, defiops, protoco await dai.approve(vaultSavings.address, 50, { from: user2 }); await ( vaultSavings).methods['deposit(address,address[],uint256[])']( vaultProtocol.address, [dai.address], [50], { from: user2 }); + + await dai.approve(strategy.address, 10000, {from: protocolStub}); }); afterEach(async() => { @@ -1003,8 +1005,189 @@ contract('VaultSavings', async([ _, owner, user1, user2, user3, defiops, protoco }); - it('Deposit with some users earned yield', async() => { - // TODO + it('Deposit/Withdraw with some users earned yield', async() => { + //user1 80 + //user2 50 + const initialAmounts = { + user1: 80, + user2: 50 + } + + let addDeposits = { + one: 30, + two: 30 + } + + let addWithdrawals = { + one: 10, + two: 10 + } + + let yieldStub = { + one: 26, + two: 26, + three: 26 + } + //Move initial deposit to protocol + await vaultSavings.handleOperatorActions(vaultProtocol.address, strategy.address, ZERO_ADDRESS, { from: defiops }); + + let totalSupply = await poolToken.totalSupply(); + let poolUser1 = await poolToken.balanceOf(user1); + let poolUser2 = await poolToken.balanceOf(user2); + + expect(totalSupply.toNumber(), "Incorrect amount of LP tokens minted").to.equal(initialAmounts.user1 + initialAmounts.user2); + expect(poolUser1.toNumber(), "Incorrect intial amount of LP tokens for User1").to.equal(initialAmounts.user1); + expect(poolUser2.toNumber(), "Incorrect intial amount of LP tokens for User2").to.equal(initialAmounts.user2); + + //Add yield to the protocol + await dai.transfer(protocolStub, yieldStub.one, { from: owner }); + + //First additional deposit from user1 + await dai.approve(vaultSavings.address, addDeposits.one, { from: user1 }); + await ( vaultSavings).methods['deposit(address,address[],uint256[])'](vaultProtocol.address, [dai.address], [addDeposits.one], { from: user1 }); + + //No distributions yet - no pool tokens for yield + totalSupply = await poolToken.totalSupply(); + poolUser1 = await poolToken.balanceOf(user1); + poolUser2 = await poolToken.balanceOf(user2); + let distrUser1 = await poolToken.distributionBalanceOf(user1); + let distrUser2 = await poolToken.distributionBalanceOf(user2); + + expect(totalSupply.toNumber(), "Incorrect amount of LP tokens minted (2)").to.equal(initialAmounts.user1 + initialAmounts.user2 + addDeposits.one); + expect(poolUser1.toNumber(), "Incorrect amount of LP tokens for User1 (2)").to.equal(initialAmounts.user1 + addDeposits.one); + expect(distrUser1.toNumber(), "Incorrect distribution amount for User1 (2)").to.equal(initialAmounts.user1); + expect(poolUser2.toNumber(), "Incorrect amount of LP tokens for User2 (2)").to.equal(initialAmounts.user2); + expect(distrUser2.toNumber(), "Incorrect distribution amount for User2 (2)").to.equal(initialAmounts.user2); + + //Add yield to the protocol + await dai.transfer(protocolStub, yieldStub.two, { from: owner }); + + //Resolve deposit + await vaultSavings.handleOperatorActions(vaultProtocol.address, strategy.address, ZERO_ADDRESS, { from: defiops }); + + totalSupply = await poolToken.totalSupply(); + poolUser1 = await poolToken.balanceOf(user1); + poolUser2 = await poolToken.balanceOf(user2); + distrUser1 = await poolToken.distributionBalanceOf(user1); + distrUser2 = await poolToken.distributionBalanceOf(user2); + + let poolAmount = await poolToken.balanceOf(poolToken.address); + + let unclaimedUser1 = await poolToken.calculateUnclaimedDistributions(user1); + let unclaimedUser2 = await poolToken.calculateUnclaimedDistributions(user2); + //LP tokens calculation + //user1: 80 (initial) + 30 (add - don't participate in yield) + 16 (one yield) + 16(two yield) = 142 + //user2: 50 (initial) + 10 (one yield) + 10 (two yield) = 70 + let totalSupplyCalc1 = initialAmounts.user1 + initialAmounts.user2 + addDeposits.one + yieldStub.one + yieldStub.two; + + //Yield calculation: + // one: 26, two: 26 + // user1: 80 working tokens + 30 on-hold -> 80 / 130 from yield -> 16 + 16 LP from yield + // user2: 50 working tokens -> 50 / 130 from yield -> 10 + 10 LP from yield + + let yieldOne = { + user1: 16 + 16, + user2: 10 + 10 + } + //First distribution from the operation action + let distrOne = await poolToken.distributions(0); + expect(distrOne[1].toNumber(), "Incorrect supply for the first distribution").to.equal(initialAmounts.user1 + initialAmounts.user2); + expect(distrOne[0].toNumber(), "Incorrect yield for the first distribution").to.equal(yieldStub.one + yieldStub.two); + + //User1 gets claim from the first distribution, because on-hold amount was changed -> distribution balance was changed + let poolTokensUser1 = initialAmounts.user1 + addDeposits.one + yieldOne.user1; + + expect(totalSupply.toNumber(), "Incorrect amount of LP tokens minted (3)").to.equal(totalSupplyCalc1); + expect(poolAmount.toNumber(), "Incorrect amount of LP tokens on pool (3)").to.equal(yieldOne.user2); + + expect(poolUser1.toNumber(), "Incorrect amount of LP tokens for User1 (3)").to.equal(poolTokensUser1); + expect(distrUser1.toNumber(), "Incorrect distribution amount for User1 (3)").to.equal(poolTokensUser1); //Now all tokens are working + expect(unclaimedUser1.toNumber(), "Incorrect unclaimed amount of LP tokens for User1 (3)").to.equal(0); + expect(poolUser2.toNumber(), "Incorrect amount of LP tokens for User2 (3)").to.equal(initialAmounts.user2); + expect(distrUser2.toNumber(), "Incorrect distribution amount for User2 (3)").to.equal(initialAmounts.user2); //Except unclaimed yield + expect(unclaimedUser2.toNumber(), "Incorrect unclaimed amount of LP tokens for User2 (3)").to.equal(yieldOne.user2); + + + //Add yield to the protocol + await dai.transfer(protocolStub, yieldStub.three, { from: owner }); + await blockTimeTravel(await poolToken.DISTRIBUTION_AGGREGATION_PERIOD()); + + //Withdraw by user1 after distribution period + await vaultSavings.withdraw(vaultProtocol.address, [dai.address], [10], false, { from: user1 }); + await vaultSavings.handleOperatorActions(vaultProtocol.address, strategy.address, ZERO_ADDRESS, { from: defiops }); + + //First distribution from the operation action + let distrTwo = await poolToken.distributions(1); + let distrTwoSupply = distrOne[1].add(distrOne[0]).toNumber() + unclaimedUser2.toNumber(); //Unclaimed included + expect(distrTwo[1].toNumber(), "Incorrect supply for the second distribution").to.equal(distrTwoSupply); + expect(distrTwo[0].toNumber(), "Incorrect yield for the second distribution").to.equal(yieldStub.three); + + totalSupply = await poolToken.totalSupply(); + poolUser1 = await poolToken.balanceOf(user1); + poolUser2 = await poolToken.balanceOf(user2); + distrUser1 = await poolToken.distributionBalanceOf(user1); + distrUser2 = await poolToken.distributionBalanceOf(user2); + poolAmount = await poolToken.balanceOf(poolToken.address); + + let totalSupplyCalc2 = totalSupplyCalc1 + yieldStub.three - addWithdrawals.one; + //Distribution was created (since distribution balance changed for user1) + //Claims are not sent to user2 since his balance was not changed + let poolAmountCalc2 = unclaimedUser2.toNumber() + yieldStub.three; + + unclaimedUser1 = await poolToken.calculateUnclaimedDistributions(user1); + unclaimedUser2 = await poolToken.calculateUnclaimedDistributions(user2); + + //Yield calculation: + // three: 26 yield + // user1: 110 from deposit + 32 from yield - 10 from withdraw = 132 LP tokens + // user2: 50 from deposit + 20 unclaied on pool token contract = 70 LP tokens + // total: 202 LP tokens + // Yield for user1: 132 / 202 = 16 (with rouding) + // Yield for user2: 70 / 202 = 9 (with rounding) + let yieldTwo = { + user1: 16, + user2: 9 + } + + expect(totalSupply.toNumber(), "Incorrect amount of LP tokens minted (4)").to.equal(totalSupplyCalc2); + expect(poolAmount.toNumber(), "Incorrect amount of LP tokens on pool (4)").to.equal(poolAmountCalc2); + + expect(poolUser1.toNumber(), "Incorrect amount of LP tokens for User1 (4)").to.equal(poolTokensUser1 - addWithdrawals.one); + expect(distrUser1.toNumber(), "Incorrect distribution amount for User1 (4)").to.equal(poolTokensUser1 - addWithdrawals.one); //The newest withdrawal ignored + expect(unclaimedUser1.toNumber(), "Incorrect unclaimed amount of LP tokens for User1 (4)").to.equal(yieldTwo.user1); + expect(poolUser2.toNumber(), "Incorrect amount of LP tokens for User2 (4)").to.equal(initialAmounts.user2); + expect(distrUser2.toNumber(), "Incorrect distribution amount for User2 (4)").to.equal(initialAmounts.user2); //Except unclaimed + expect(unclaimedUser2.toNumber(), "Incorrect unclaimed amount of LP tokens for User2 (4)").to.equal(yieldOne.user2 + yieldTwo.user2);//All unclaimed + + + + //Add yield to the protocol + await dai.transfer(protocolStub, 26, { from: owner }); + //Deposit by user1 before distribution period + await dai.approve(vaultSavings.address, addDeposits.two, { from: user1 }); + await ( vaultSavings).methods['deposit(address,address[],uint256[])'](vaultProtocol.address, [dai.address], [addDeposits.two], { from: user1 }); + + totalSupply = await poolToken.totalSupply(); + poolUser1 = await poolToken.balanceOf(user1); + poolUser2 = await poolToken.balanceOf(user2); + distrUser1 = await poolToken.distributionBalanceOf(user1); + distrUser2 = await poolToken.distributionBalanceOf(user2); + poolAmount = await poolToken.balanceOf(poolToken.address); + + unclaimedUser1 = await poolToken.calculateUnclaimedDistributions(user1); + unclaimedUser2 = await poolToken.calculateUnclaimedDistributions(user2); + + poolTokensUser1 = initialAmounts.user1 + addDeposits.one + yieldOne.user1 - addWithdrawals.one; + + expect(totalSupply.toNumber(), "Incorrect amount of LP tokens minted (5)").to.equal(totalSupplyCalc2 + addDeposits.two); + + //Since distribution amount changed - user gets all unclaimed + expect(poolUser1.toNumber(), "Incorrect amount of LP tokens for User1 (5)").to.equal(poolTokensUser1 + addDeposits.two + yieldTwo.user1); + expect(distrUser1.toNumber(), "Incorrect distribution amount for User1 (5)").to.equal(poolTokensUser1 + yieldTwo.user1); //Without on-hold + expect(unclaimedUser1.toNumber(), "Incorrect unclaimed amount of LP tokens for User1 (5)").to.equal(0); + expect(poolUser2.toNumber(), "Incorrect amount of LP tokens for User2 (5)").to.equal(initialAmounts.user2); //Unchanged + expect(distrUser2.toNumber(), "Incorrect distribution amount for User2 (5)").to.equal(initialAmounts.user2); //Except unclaimed + expect(unclaimedUser2.toNumber(), "Incorrect unclaimed amount of LP tokens for User2 (5)").to.equal(yieldOne.user2 + yieldTwo.user2);//All unclaimed }); }); @@ -1348,6 +1531,89 @@ contract('VaultSavings', async([ _, owner, user1, user2, user3, defiops, protoco expect(unclaimedTokens.toNumber(), 'No yield for user (2)').to.equal(10); }); + it('Correct distribution for the new user (after several distributions)', async() => { + //Deposited 80 by user1 and 50 by user2 + + //Operator action + await vaultSavings.handleOperatorActions(vaultProtocol.address, strategy.address, ZERO_ADDRESS, { from: defiops }) + + //First distribution (adfter additional deposit) + //Yield + await dai.transfer(protocolStub, 26, { from: owner }); + + //Deposit again + await dai.approve(vaultSavings.address, 50, { from: user1 }); + await ( vaultSavings).methods['deposit(address,address[],uint256[])'](vaultProtocol.address, [dai.address], [50], { from: user1 }); + await dai.approve(vaultSavings.address, 50, { from: user2 }); + await ( vaultSavings).methods['deposit(address,address[],uint256[])'](vaultProtocol.address, [dai.address], [50], { from: user2 }); + + // Operator action + await vaultSavings.handleOperatorActions(vaultProtocol.address, strategy.address, ZERO_ADDRESS, { from: defiops }); + + //Distribution was created + //User1: 80 (deposited) + 50 (new) + 80/130 * 26 = 16 of new yield + //User2: 50 (deposited) + 50 (new) + 50/130 * 26 = 10 of new yield + + //Create second distribution + //Yield + await dai.transfer(protocolStub, 128, { from: owner }); + + //Distribute yield + await blockTimeTravel(await poolToken.DISTRIBUTION_AGGREGATION_PERIOD()); + await vaultSavings.distributeYield(vaultProtocol.address, {from:defiops}); + + //Second distribution + //User1: 130 (deposited) + 16 of previous yield + 146/256 * 128 = 73 + //User2: 100 (deposited) + 10 of previous yield + 110/256 * 128 = 55 + + //Deposit from new user + + //New user deposit + await dai.approve(vaultSavings.address, 60, { from: user3 }); + await ( vaultSavings).methods['deposit(address,address[],uint256[])'](vaultProtocol.address, [dai.address], [60], { from: user3 }); + + let distrNum = await poolToken.nextDistributions(user3); + expect(distrNum.toNumber(), "Incorrect distribution number").to.equal(2); //The next after 2 distributions (starting with 0) + + let unclaimed = await poolToken.calculateUnclaimedDistributions(user3); + expect(unclaimed.toNumber(), "Should not have unclaimed tokens").to.equal(0); + + let distrTokens = await poolToken.distributionBalanceOf(user3); + expect(distrTokens.toNumber(), "Should not have distribution balance yet").to.equal(0); //Tokens are on-hold + + //operatorAction + await vaultSavings.handleOperatorActions(vaultProtocol.address, strategy.address, ZERO_ADDRESS, { from: defiops }); + + distrNum = await poolToken.nextDistributions(user3); + expect(distrNum.toNumber(), "Incorrect distribution number (2)").to.equal(2); //The next after 2 distributions (starting with 0) + + unclaimed = await poolToken.calculateUnclaimedDistributions(user3); + expect(unclaimed.toNumber(), "Should not have unclaimed tokens (2)").to.equal(0); + + distrTokens = await poolToken.distributionBalanceOf(user3); + expect(distrTokens.toNumber(), "Incorrect distribution balance").to.equal(60); //Deposit is on strategy now + + //Create the third distribution + //Yield + await dai.transfer(protocolStub, 148, { from: owner }); + + //Distribute yield + await blockTimeTravel(await poolToken.DISTRIBUTION_AGGREGATION_PERIOD()); + await vaultSavings.distributeYield(vaultProtocol.address, {from:defiops}); + + //Third distribution + //Supply for distribution: 219 + 165 + 60 = 444 + //User1: 130 (deposited) + (73 + 16) of previous yield + 219/444 * 148 = 73 + //User2: 100 (deposited) + (55 + 10) of previous yield + 165/444 * 148 = 55 + //User3: 60 (deposited) + + 60/444 * 148 = 20 + + distrNum = await poolToken.nextDistributions(user3); + expect(distrNum.toNumber(), "Incorrect distribution number (3)").to.equal(2); + + unclaimed = await poolToken.calculateUnclaimedDistributions(user3); + expect(unclaimed.toNumber(), "Incorrect unclaimed amount").to.equal(20); //Calculated yield for user3 + }); + }); describe('Full cycle', () => {