diff --git a/packages/contracts/addresses-staging.json b/packages/contracts/addresses-staging.json deleted file mode 100644 index 7490a05d3..000000000 --- a/packages/contracts/addresses-staging.json +++ /dev/null @@ -1,442 +0,0 @@ -{ - "421614": { - "GraphProxyAdmin": { - "address": "0xC8621C8Aa286Aac28551565C4c2E367F5b5De583", - "creationCodeHash": "0x68b304ac6bce7380d5e0f6b14a122f628bffebcc75f8205cb60f0baf578b79c3", - "runtimeCodeHash": "0x8d9ba87a745cf82ab407ebabe6c1490197084d320efb6c246d94bcc80e804417", - "txHash": "0x2b9ffd8b4062728da184f0545906af12ded857b323ba8379894c69a6758bc2d1" - }, - "Controller": { - "address": "0x1eB3dC938d1Bc573D657d3cF05F48523773EADd3", - "creationCodeHash": "0x5bde9a87bc4e8dd24d41900f0a19321c1dc6d3373d51bba093b130bb5b80a677", - "runtimeCodeHash": "0x7f0479db1d60ecf6295d92ea2359ebdd223640795613558b0594680f5d4922c9", - "txHash": "0x5fbc3b23ea4bfc9fa34c7cd112723fcbc7614af03f0fd42a170b6ab397d8505f" - }, - "EpochManager": { - "address": "0x969A82ca85Efc62Cca8e88D64f74Ef89C002AE62", - "initArgs": ["0x1eB3dC938d1Bc573D657d3cF05F48523773EADd3", "554"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0xa30e76aa2e1581d19dec1e5ef419ded2f8b21e250fe52670bff6b28d20cf23d8", - "proxy": true, - "implementation": { - "address": "0x9D2FC0A47081faDA1a981E1e2bfcdCE600254914", - "creationCodeHash": "0x46f6e557c33712422a496a5955626504bfabefc242ef8eacea07324427baf467", - "runtimeCodeHash": "0x3a5ccaf8a8f67fa727849a5636d46b92a29f9838c14cca20a15fdef0e8f78c61", - "txHash": "0x3b6627842e8f2a1e19a793ebade4f7489b5bef7d9bb8a62f103fe2c6f4eda23f" - } - }, - "L2GraphToken": { - "address": "0x9975A2a0bFf669c69b2fEF885C94A5bfCffB8626", - "initArgs": ["0xadE6B8EB69a49B56929C1d4F4b428d791861dB6f"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x9b0d13fb3dc313881f0b17b1a44ba08faeced2dbaddb94993d4f157dc835c0b8", - "proxy": true, - "implementation": { - "address": "0xa567c06921c80f8f23E64D2FeD2EdaAafC87b8D6", - "creationCodeHash": "0x6c4146427aafa7375a569154be95c8c931bf83aab0315706dd78bdf79c889e4c", - "runtimeCodeHash": "0x004371d1d80011906953dcba17c648503fc94b94e1e0365c8d8c706ff91f93e9", - "txHash": "0x6dafb8c05dac61c35ce97605643da00293317d1087dec05c79ffeb5275900126" - } - }, - "GraphCurationToken": { - "address": "0xf3172c87417d2E07806F278Da87bB7dc22E55E92", - "creationCodeHash": "0x1ee42ee271cefe20c33c0de904501e618ac4b56debca67c634d0564cecea9ff2", - "runtimeCodeHash": "0x340e8f378c0117b300f3ec255bc5c3a273f9ab5bd2940fa8eb3b5065b21f86dc", - "txHash": "0xf6b46423a006f6c9edb38aacae40dcf0e417345c53d59a6693e83623e9cccac4" - }, - "ServiceRegistry": { - "address": "0x174ED56255FdB19754834eB11C116c288288c23F", - "initArgs": ["0x1eB3dC938d1Bc573D657d3cF05F48523773EADd3"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0xe23b2ce8024d8a603a617f7f685b298a1079f3e0fecd2ef3f47fe5200dd062f2", - "proxy": true, - "implementation": { - "address": "0xF3d33Cf20628EF30220ab7DAA151c45dC600d4BD", - "creationCodeHash": "0x0fdb1360692ba7459a580610706838c1d9dbffa2117a5c9433ca4ce3491e9b35", - "runtimeCodeHash": "0x3f99c39e90540c307e0a38ecbe501a3bb47f9916319179491214e07c55319666", - "txHash": "0xb52b836c1d4555a0f6cc08f9c18f9df1e382dddba4522d5ecfcbd637a6c76685" - } - }, - "L2Curation": { - "address": "0xddd1ab948602a365dE04E7153EbC2D401Be550C7", - "initArgs": [ - "0x1eB3dC938d1Bc573D657d3cF05F48523773EADd3", - "0xf3172c87417d2E07806F278Da87bB7dc22E55E92", - "10000", - "1" - ], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x9346e8c6133211590867ebe9bee37efb44f52175ee7ce498a57a78d1223e6357", - "proxy": true, - "implementation": { - "address": "0x60d946bCAC1bcd99dA79cdd37bd4cAAb1f739A1F", - "creationCodeHash": "0x2287d9023bf7d91e688e1eb029eff7657ef3b87e37b5222b01fd50985d0928f9", - "runtimeCodeHash": "0xd799b2b74e9634d6b6ef15b5710409264bed04a60f9519b9d8f05ac183199d16", - "txHash": "0xae41519e9620042b88b76a39fec00946a17cf41d47b659351a967cc86dbc1b53" - } - }, - "SubgraphNFTDescriptor": { - "address": "0x98EC4455196901C129Fa518Caea96Ab03A713c82", - "creationCodeHash": "0xf16e8ff11d852eea165195ac9e0dfa00f98e48f6ce3c77c469c7df9bf195b651", - "runtimeCodeHash": "0x39583196f2bcb85789b6e64692d8c0aa56f001c46f0ca3d371abbba2c695860f", - "txHash": "0x3841019cc9e64ec50446a93d2c59a21ea579533c289d944a7cf17197427ddb1a" - }, - "SubgraphNFT": { - "address": "0xB4C1c4998f547679841714ae3E2241543b52Ca85", - "constructorArgs": ["0xadE6B8EB69a49B56929C1d4F4b428d791861dB6f"], - "creationCodeHash": "0xc1e58864302084de282dffe54c160e20dd96c6cfff45e00e6ebfc15e04136982", - "runtimeCodeHash": "0x7216e736a8a8754e88688fbf5c0c7e9caf35c55ecc3a0c5a597b951c56cf7458", - "txHash": "0x36a456898f3addfa9e4eb459fd79862216012639360d69574b0fec06bce56fe2" - }, - "L2GNS": { - "address": "0xE0e09986912E7723c28Cc81c01c0B6b2789B7ff7", - "initArgs": ["0x1eB3dC938d1Bc573D657d3cF05F48523773EADd3", "0xB4C1c4998f547679841714ae3E2241543b52Ca85"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0xbd2d3f6d4fee611c5f090da74c1abcb83274fc9deb3e57f9903ce6e6eb7c3d2c", - "proxy": true, - "implementation": { - "address": "0x5792f9a70DE8c58D8df1A03E6CEc72fe1e14fc4B", - "creationCodeHash": "0xd71f45e6c194920a26f90fcec96d8c3375f02c5aef8ad90c1be24e906ffe8342", - "runtimeCodeHash": "0x68ec24512fedb866d7ba7ba6c02160317d0ca34eaacd23bddcc62d2cbcd9869c", - "txHash": "0x1b9b13111d5647b8f3f73567c00d81abc95296fb885c346a454df4f80d3cda23" - } - }, - "StakingExtension": { - "address": "0x36C27F2DFa4F3bAF609d8E53D7Dd1A5e64eA9266", - "creationCodeHash": "0x7ae74140871330ecabb7040182dc8288c2c84693393a519230036f39c2281138", - "runtimeCodeHash": "0x4994aa74e9e29c36a8158af690a245ccd1cf4d955223e5fcb1ca62810b37ed57", - "txHash": "0xe96b9221e789496baf1718190c05e54d5d4a96049acfca0158f836d0f464849f" - }, - "L2Staking": { - "address": "0x3fC01c0E957Ca1c8C7E94Edd4497A6d6B1ED9b73", - "initArgs": [ - "0x1eB3dC938d1Bc573D657d3cF05F48523773EADd3", - "100000000000000000000000", - "6646", - "10000", - "100000", - "8", - "12", - "16", - "100,100,60,100", - "0x9291448138A18CE5329470417AE5f3cba1D974Ed" - ], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x5ae51383f5ad1e434a78c2a6d5393d497be315c40287d827c63c4ca48cc66aca", - "proxy": true, - "implementation": { - "address": "0x0a6b1efb7b2e9A27Cf7C5ED1bdF1Bd03bF8F5600", - "creationCodeHash": "0x60bc1fda6913ef750a1d931e87068d0f6cd62b8b42a4fff13b304b9c0c278557", - "runtimeCodeHash": "0xd8bbd97b94f8ac45a479c55c0416e7b0ebef6a99da8ef7580bebaaad1d8d74d9", - "txHash": "0x5d9276e47f3d1fa1fe5c6d826534722aa73d47f5a114e844de73a3cf0cb22d6b", - "libraries": { - "LibExponential": "0xb7fB963257d4f31F88021d2D7Ee53688e38A0938" - } - } - }, - "RewardsManager": { - "address": "0x00b9d319E3D09E83c62f453B44354049Dd93a345", - "initArgs": ["0x1eB3dC938d1Bc573D657d3cF05F48523773EADd3"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x6f29e2f24dcdcbf5ed62e64434a1cd421b095d6199e7beb609de240986b1c066", - "proxy": true, - "implementation": { - "address": "0xc29119C524BDad22AC9dc19318Dc3a68EA636A86", - "creationCodeHash": "0x5e2ca01e204a1bd3a41a73ebe9a43679155351c96a6dc59d44e02c6dd0e5bed4", - "runtimeCodeHash": "0x64f77ec9ceffb764ff8677bae252f065fb04ef6974816002d979517ea8616cf7", - "txHash": "0xfc21ca24c15671457e93825936dab630e065c0794e9f6eaca4973452a3673435" - } - }, - "DisputeManager": { - "address": "0xdF0e0BAC295754207E6F36d6C90326d18354a1f0", - "initArgs": [ - "0x1eB3dC938d1Bc573D657d3cF05F48523773EADd3", - "0x1726A5d52e279d02ff4732eCeB2D67BFE5Add328", - "10000000000000000000000", - "500000", - "25000", - "25000" - ], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x466f67046c81847e5d7746471ebbd255ab721c7ee85e85520254513b10745e7b", - "proxy": true, - "implementation": { - "address": "0x800C6152ae29C39B7fA4d40079017140d3A81fB4", - "creationCodeHash": "0xce4c47d94a33d69e03d607dd13a9ad1ed7fa730ef4a2308eb56ddd646ebaa0aa", - "runtimeCodeHash": "0x18d4a1659ccecede3d4d305ef1db4653d8f3dcbd4012f4e52200ae9f0c6c322c", - "txHash": "0x245066977ce08f06ce90add71cdf1c366bd9c8c0cb08fd6998a8ca2ac8758185" - } - }, - "AllocationExchange": { - "address": "0xa79F0861a0Bf975a6a7859Bd27C5f85AfAb559b3", - "constructorArgs": [ - "0x9975A2a0bFf669c69b2fEF885C94A5bfCffB8626", - "0x3fC01c0E957Ca1c8C7E94Edd4497A6d6B1ED9b73", - "0x72ee30d43Fb5A90B3FE983156C5d2fBE6F6d07B3", - "0x49D4CFC037430cA9355B422bAeA7E9391e1d3215" - ], - "creationCodeHash": "0x9731f46fbd12dbfbb066e0c291551ef1854cb54dd651632abb37322f6437ac18", - "runtimeCodeHash": "0xf2371afaa31bdaae67f43a2a0f85eae64bed2bbf5df117d7c68b74a64f1d3ece", - "txHash": "0x848b9f43ec851f6509443ba67c43e8d6748ceea8f6d60087ae98576aca5a4a4f" - }, - "L2GraphTokenGateway": { - "address": "0xDDE8A47Eb0394f3c7D5d143d6bCE9Dd0Ee0f6617", - "initArgs": ["0x1eB3dC938d1Bc573D657d3cF05F48523773EADd3"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x74179b89785ffbdbae2cc61161e1addc69c243dabd298796eb6ebc4299908e8e", - "proxy": true, - "implementation": { - "address": "0x748def5e70F69bBFD0770f2d1dE44e860e8759F4", - "creationCodeHash": "0x0190953f43ab8d61923de0edd8f8d28da4e12a90330f0030b19a497496c36039", - "runtimeCodeHash": "0xd853da2001c213dd00d674114c254f18a7b5a36aabc5452fb492b9b4faf2faa9", - "txHash": "0xf868871475dc711c5c03818b16a922f740bc2fc314d24586df2255161a907422" - } - }, - "SubgraphAvailabilityManager": { - "address": "0xF00AA63f1a8eE67BAD135759eC7a6542b1d56a8f", - "constructorArgs": [ - "0x72ee30d43Fb5A90B3FE983156C5d2fBE6F6d07B3", - "0x00b9d319E3D09E83c62f453B44354049Dd93a345", - "3", - "300", - [ - "0xb4d396a40BB976118Bb2c9DB9C5539e65c7Fe64A", - "0x633259dB4A33DB664d4C3Fa57BEc45E5030131E2", - "0x9FC436A69E290227b99A9CE0468a1b9D73068E80", - "0xC9b90ab0B9cA63fDBfB46f66BE813ea94561614d", - "0xf3B8F917EcFA569089CF6A0988F9a9F5155cEF83" - ] - ], - "creationCodeHash": "0xc34842fa42ee2f21e3a435b52fa69a122a5de795448faa890fbc63d4838f45da", - "runtimeCodeHash": "0xe6c0ccd0b0514dd55e58806b1c84f09805dd6202985722579c11d7e252df6b8d", - "txHash": "0x5c1dd91c76e547fe31a5df822353b50e93eb795b915aac0ea8f8364229e9c29c" - } - }, - "11155111": { - "GraphProxyAdmin": { - "address": "0x6f1F77Cc8Ee39f45CCd25B4EccE2cedB47ccb8bF", - "creationCodeHash": "0x68b304ac6bce7380d5e0f6b14a122f628bffebcc75f8205cb60f0baf578b79c3", - "runtimeCodeHash": "0x8d9ba87a745cf82ab407ebabe6c1490197084d320efb6c246d94bcc80e804417", - "txHash": "0xb195b1b16aa45669da0b4b530d0561ebad1b458011128d98f0c8f2974ea221d7" - }, - "BancorFormula": { - "address": "0x959f6d7Af76e22fF2459990e257eeD96ce2c99B4", - "creationCodeHash": "0x7ae36017eddb326ddd79c7363781366121361d42fdb201cf57c57424eede46f4", - "runtimeCodeHash": "0xed6701e196ad93718e28c2a2a44d110d9e9906085bcfe4faf4f6604b08f0116c", - "txHash": "0x57a4c36f7e36f3959d8ed517d2ca3d7a161aba5076b059e03efc291ff48e70be" - }, - "Controller": { - "address": "0x030C73c651445310bcc568449E956e2A976F1a29", - "creationCodeHash": "0x5bde9a87bc4e8dd24d41900f0a19321c1dc6d3373d51bba093b130bb5b80a677", - "runtimeCodeHash": "0x7f0479db1d60ecf6295d92ea2359ebdd223640795613558b0594680f5d4922c9", - "txHash": "0x8630416fb4633b3498962e8b4b824d25007664c7ed71eed170ef1c90eabb0c0f" - }, - "EpochManager": { - "address": "0x7783C76139371E38c0631073B51F3110Cb3A5822", - "initArgs": ["0x030C73c651445310bcc568449E956e2A976F1a29", "554"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0xf2dbef208ce21665b5e707ad8ef45a2df2d3f45ffdc31a69c22c70a74c712295", - "proxy": true, - "implementation": { - "address": "0xB0f81EcE835C1b13C18973e9fFEbb6787765157D", - "creationCodeHash": "0x46f6e557c33712422a496a5955626504bfabefc242ef8eacea07324427baf467", - "runtimeCodeHash": "0x3a5ccaf8a8f67fa727849a5636d46b92a29f9838c14cca20a15fdef0e8f78c61", - "txHash": "0x80e35b38cf3153e08cbfd576d370f43ed4c3a6e7b48057c46201f6d2bf829d13" - } - }, - "GraphToken": { - "address": "0xf67bE354953C7ccA1B92F3F489a4774dc856062e", - "constructorArgs": ["10000000000000000000000000000"], - "creationCodeHash": "0x9c50586e9e305b3a299f1cdf92ca9bb04fad5f43b5e0f7505054d79783fd8b69", - "runtimeCodeHash": "0xfe612acbb09bdb23fe60014e890054621fd34d74bf12bd94fb73351d474cd641", - "txHash": "0x03ca50bc408a3f974d535f5de3aef23d4840324e0d9da4dc3348d8c8a5d70b7b" - }, - "GraphCurationToken": { - "address": "0xD432feaf373aaBC8ffAbaC66FEB753f2F531fAD2", - "creationCodeHash": "0x1ee42ee271cefe20c33c0de904501e618ac4b56debca67c634d0564cecea9ff2", - "runtimeCodeHash": "0x340e8f378c0117b300f3ec255bc5c3a273f9ab5bd2940fa8eb3b5065b21f86dc", - "txHash": "0x4f9de94c643a64ed245cc921e0cb7ff4175be4506fdba53b136c2a4c9109bde1" - }, - "ServiceRegistry": { - "address": "0x8E4dF72703Cd2b74e25fFE01C492F4b7F5D6Cdc4", - "initArgs": ["0x030C73c651445310bcc568449E956e2A976F1a29"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0xe748f733b11d532a266ea2ffe0a671fb329e60ca7dc6d74e33fe8e6f173fed4c", - "proxy": true, - "implementation": { - "address": "0x7f3d488ccaEE5153955F321654A88F19a48AD5Ba", - "creationCodeHash": "0x0fdb1360692ba7459a580610706838c1d9dbffa2117a5c9433ca4ce3491e9b35", - "runtimeCodeHash": "0x3f99c39e90540c307e0a38ecbe501a3bb47f9916319179491214e07c55319666", - "txHash": "0x1c0e82fc0aa229f9fea138e714da90a560ea6e84c106d2a74905979cc265d998" - } - }, - "Curation": { - "address": "0x6E5Aef53761D4591947A757781f68df91031C29B", - "initArgs": [ - "0x030C73c651445310bcc568449E956e2A976F1a29", - "0x959f6d7Af76e22fF2459990e257eeD96ce2c99B4", - "0xD432feaf373aaBC8ffAbaC66FEB753f2F531fAD2", - "500000", - "10000", - "1000000000000000000" - ], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x2cbe736f1afb13a6b7d12fa191d3d5ab40d39fe07465e2c188223dcca28b7c48", - "proxy": true, - "implementation": { - "address": "0x1B22551D83f2C3850D4715d979AD0186d9fbd4D8", - "creationCodeHash": "0x664014c4a6cde182892a64e4e86424567fcd478489bbcab9368f7fb970be02f5", - "runtimeCodeHash": "0x66925e4da1aacafc21adda65172c907eb7719d0dcce003d041e67f0369c064fd", - "txHash": "0xbd65e43da71ee9efb7865b77afc6d546be5320685b6b99956d28ccf0a7a44e6a" - } - }, - "SubgraphNFTDescriptor": { - "address": "0xad6bb620CA8f2e92Dfb34Bca6fE40acD101A175E", - "creationCodeHash": "0xf16e8ff11d852eea165195ac9e0dfa00f98e48f6ce3c77c469c7df9bf195b651", - "runtimeCodeHash": "0x39583196f2bcb85789b6e64692d8c0aa56f001c46f0ca3d371abbba2c695860f", - "txHash": "0xf690f7e5d0df4b2ce0b528097f0bae96ed6e420bc382229f8a15b810ab4aa0ad" - }, - "SubgraphNFT": { - "address": "0x0d12A34c88D2753f6523E5Ac5942a0c7b60d1448", - "constructorArgs": ["0x559081D91F5Ff43dfE51A07C216F8E6893805B35"], - "creationCodeHash": "0xc1e58864302084de282dffe54c160e20dd96c6cfff45e00e6ebfc15e04136982", - "runtimeCodeHash": "0x7216e736a8a8754e88688fbf5c0c7e9caf35c55ecc3a0c5a597b951c56cf7458", - "txHash": "0xf8d71e696a453d28aad2949d5c502bfb00a70350c52fd74fb8f2416b62e39da6" - }, - "L1GNS": { - "address": "0x4A952e8eF0373471ac44F71b540BE9164430E8Eb", - "initArgs": ["0x030C73c651445310bcc568449E956e2A976F1a29", "0x0d12A34c88D2753f6523E5Ac5942a0c7b60d1448"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x779bb878b6a8d2f741650e02d53ae5b89a85e326aa25d49866f9914dc5794132", - "proxy": true, - "implementation": { - "address": "0xC9845CbC22F782c7397A6b4DfF7E739dD2364FB8", - "creationCodeHash": "0x36331afa041aa06c3c5beda1287c183e6193d65a6b61e34aaedb2929e9843bda", - "runtimeCodeHash": "0x5876f25be6e6ac09fd495aa04d88fa911d27d1c9e7359d87aaf84b9be2c49faa", - "txHash": "0x93e673dee281a86c99809d65c61e73bf30336b533023b30177d55671f1975f21" - } - }, - "StakingExtension": { - "address": "0xE792fa7bfF436Fbe9Ea6569201009061938d4e93", - "creationCodeHash": "0x8de9e9fe7e46fd75fee0be1fa10bc1c250532991c123db106bb3bad01ac9046b", - "runtimeCodeHash": "0xa9215542f24456fb4c63cc8684699255f85d29a0cf611d3dc7191b1445716376", - "txHash": "0x965bfbdd003a8069fd67461bccb69130da7f3efab5aa879b41cc4c7d1755939b" - }, - "L1Staking": { - "address": "0xBDEA90C996E9b92240fbef95989e51F86045afDb", - "initArgs": [ - "0x030C73c651445310bcc568449E956e2A976F1a29", - "100000000000000000000000", - "6646", - "10000", - "100000", - "4", - "12", - "16", - "100,100,60,100", - "0xE792fa7bfF436Fbe9Ea6569201009061938d4e93" - ], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x35abe8a983f99476858fe5278a3ce2d5975b2c731ac89772cfbe2d2442acd21c", - "proxy": true, - "implementation": { - "address": "0x775e5672eE18eFA0fCc8C3F4C261bD3B61004897", - "creationCodeHash": "0xf885b3ef0b27a702c25eed9c767fe15d26bde96c0b343b8119a7fe02653d99c6", - "runtimeCodeHash": "0x5ac75f1f9973309e604d60ffa33d435af80792c80231fc0c06903e5c0331f7ac", - "txHash": "0xb4e0b72af1e712382581c3e5c5f246837f27e7a5cfb276d547c421eb2ebc8563", - "libraries": { - "LibExponential": "0x2a05d2c9fB1A9FD0d398c2DF778a6D249B532D44" - } - } - }, - "RewardsManager": { - "address": "0x9a86322dEa5136C74ee6d1b06F4Ab9A6bB2724E0", - "initArgs": ["0x030C73c651445310bcc568449E956e2A976F1a29"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0xea65aa3f292c4fca982f39b5ae5d16ba9eea02f97d8ea787af4b0f11fa8695dc", - "proxy": true, - "implementation": { - "address": "0x3b54eA540EdC2266E811B4bb6ae1791b0685f75A", - "creationCodeHash": "0x5e2ca01e204a1bd3a41a73ebe9a43679155351c96a6dc59d44e02c6dd0e5bed4", - "runtimeCodeHash": "0x64f77ec9ceffb764ff8677bae252f065fb04ef6974816002d979517ea8616cf7", - "txHash": "0x7028376b813772e89872eec90206449473cccd1f59c0dd8272ecbdc869e04f92" - } - }, - "DisputeManager": { - "address": "0xF5a7aA8793445B4803b617b4199540248D1Eef53", - "initArgs": [ - "0x030C73c651445310bcc568449E956e2A976F1a29", - "0xd6ff9e98F0Fd99ccB658832F586e23F4D8Cb8Bad", - "10000000000000000000000", - "500000", - "25000", - "25000" - ], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x979eacdafc53c91ed0f9f8078f2d4ab4a4e29fffc61add01982d4adcd14dccfd", - "proxy": true, - "implementation": { - "address": "0x98F352c0e7f31Bb9ac636F097C0d018719F72D28", - "creationCodeHash": "0xc57491ef973583304f2d179445a0cd0983c88abe321536195aa10b6602c72c05", - "runtimeCodeHash": "0x08740630f1836c12c860f717f40eeec7b4c08cb8a950f842f11fb200a3541cfd", - "txHash": "0x27f125ca77a7ceb5041d77cef5644f2bd72025b4b66898b185f6556860d72d50" - } - }, - "AllocationExchange": { - "address": "0x154E65F44918DC96ef95f15844C2f79883e11aa2", - "constructorArgs": [ - "0xf67bE354953C7ccA1B92F3F489a4774dc856062e", - "0xBDEA90C996E9b92240fbef95989e51F86045afDb", - "0x4EBf30832eC2db76aE228D5d239083B59f530d1f", - "0x840daec5dF962D49cf2EFd789c4E40A7b7e0117D" - ], - "creationCodeHash": "0x9731f46fbd12dbfbb066e0c291551ef1854cb54dd651632abb37322f6437ac18", - "runtimeCodeHash": "0x21a000835d92d4f79f062f56f02ef1618ede7a56796be7bea068a517424fc7fc", - "txHash": "0x4b6b89d10cbe3fd28dffe2411cf9e109df759e6e9e3232cb7a7f1ec91f5a05db" - }, - "L1GraphTokenGateway": { - "address": "0xd0eA0904cdb34AC4b624280f17b67DaFe57615E4", - "initArgs": ["0x030C73c651445310bcc568449E956e2A976F1a29"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x14f23e307d5ab1b6b550060dfac81974ae6a207429ad625ecd60a16fd9586df4", - "proxy": true, - "implementation": { - "address": "0xc7d4754CEbD240ec2b235d0B219a79039F536F2A", - "creationCodeHash": "0xf50c33e5a6f5c8e88485a922a1d5f2f46da965d180964d0e4a7852f97c59ce9d", - "runtimeCodeHash": "0x4e0d0eb1bafca40ef18c6f5ebe5ec408eaa00511b4e27ee508417e2bf90acc49", - "txHash": "0xc621dc678ab55ccbdf8bcdd93c24e756159574cd775fc6acfe3ffb8bf1831445" - } - }, - "BridgeEscrow": { - "address": "0x0d2692b5438EdE62ADEB83E22a8F2C45379d2C14", - "initArgs": ["0x030C73c651445310bcc568449E956e2A976F1a29"], - "creationCodeHash": "0xcdd28bb3db05f1267ca0f5ea29536c61841be5937ce711b813924f8ff38918cc", - "runtimeCodeHash": "0x4ca8c37c807bdfda1d6dcf441324b7ea14c6ddec5db37c20c2bf05aeae49bc0d", - "txHash": "0x6b4884c0bb94e8d7ab97fce14f2555235a89d0b7ec394c61b71431b5c97523e9", - "proxy": true, - "implementation": { - "address": "0x3BB0742F6B0569576A259115068cFF5EF67cdba8", - "creationCodeHash": "0xa45cfc3fe7161765a1fb0b967bfc9f5c158cb3aa43f3556c4a5cc6a6bdb1d0ef", - "runtimeCodeHash": "0x3cb8a7336234c7826c8f5a437ad2c6615c2e4b4201096a49cb6876264ac47182", - "txHash": "0xf0765b7fe12702a7de3644bb1bcd6549bce1b8b738f2136e94bf39d10521b3e3" - } - } - } -} diff --git a/packages/contracts/arbitrum-addresses.json b/packages/contracts/arbitrum-addresses.json deleted file mode 100644 index 92c63a498..000000000 --- a/packages/contracts/arbitrum-addresses.json +++ /dev/null @@ -1,55 +0,0 @@ -{ - "source": "https://developer.offchainlabs.com/docs/useful_addresses", - "1": { - "L1GatewayRouter": { - "address": "0x72Ce9c846789fdB6fC1f34aC4AD25Dd9ef7031ef" - }, - "IInbox": { - "address": "0x4Dbd4fc535Ac27206064B68FfCf827b0A60BAB3f" - } - }, - "4": { - "L1GatewayRouter": { - "address": "0x70C143928eCfFaf9F5b406f7f4fC28Dc43d68380" - }, - "IInbox": { - "address": "0x578BAde599406A8fE3d24Fd7f7211c0911F5B29e" - } - }, - "5": { - "L1GatewayRouter": { - "address": "0x4c7708168395aEa569453Fc36862D2ffcDaC588c" - }, - "IInbox": { - "address": "0x6BEbC4925716945D46F0Ec336D5C2564F419682C" - } - }, - "42161": { - "L2GatewayRouter": { - "address": "0x5288c571Fd7aD117beA99bF60FE0846C4E84F933" - } - }, - "421611": { - "L2GatewayRouter": { - "address": "0x9413AD42910c1eA60c737dB5f58d1C504498a3cD" - } - }, - "421613": { - "L2GatewayRouter": { - "address": "0xE5B9d8d42d656d1DcB8065A6c012FE3780246041" - } - }, - "421614": { - "L2GatewayRouter": { - "address": "0x9fDD1C4E4AA24EEc1d913FABea925594a20d43C7" - } - }, - "11155111": { - "L1GatewayRouter": { - "address": "0xcE18836b233C83325Cc8848CA4487e94C6288264" - }, - "IInbox": { - "address": "0xaAe29B0366299461418F5324a79Afc425BE5ae21" - } - } -} diff --git a/packages/contracts/config/graph.arbitrum-goerli.yml b/packages/contracts/config/graph.arbitrum-goerli.yml deleted file mode 100644 index 10c57d7ec..000000000 --- a/packages/contracts/config/graph.arbitrum-goerli.yml +++ /dev/null @@ -1,152 +0,0 @@ -general: - arbitrator: &arbitrator '0xF89688d5d44d73cc4dE880857A3940487076e5A4' # Arbitration Council (TODO: update) - governor: &governor '0x5CeeeE16F30357d49c50bcd7F520ca6527cf388a' # Graph Council (TODO: update) - authority: &authority '0xac01B0b3B2Dc5D8E0D484c02c4d077C15C96a7b4' # Authority that signs payment vouchers - availabilityOracle: &availabilityOracle '0xa99a56fa38a6b9553853c84e11458aeccdad509b' # Subgraph Availability Oracle (TODO: update) - pauseGuardian: &pauseGuardian '0x4B6C90B9fE29dfa521188B6547989C23d613b79B' # Protocol pause guardian (TODO: update) - allocationExchangeOwner: &allocationExchangeOwner '0x05F359b1319f1Ca9b799CB6386F31421c2c49dBA' # Allocation Exchange owner (TODO: update) - -contracts: - Controller: - calls: - - fn: 'setContractProxy' - id: '0xe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f' # keccak256('Curation') - contractAddress: '${{L2Curation.address}}' - - fn: 'setContractProxy' - id: '0x39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3' # keccak256('GNS') - contractAddress: '${{L2GNS.address}}' - - fn: 'setContractProxy' - id: '0xf942813d07d17b56de9a9afc8de0ced6e8c053bbfdcc87b7badea4ddcf27c307' # keccak256('DisputeManager') - contractAddress: '${{DisputeManager.address}}' - - fn: 'setContractProxy' - id: '0xc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063' # keccak256('EpochManager') - contractAddress: '${{EpochManager.address}}' - - fn: 'setContractProxy' - id: '0x966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761' # keccak256('RewardsManager') - contractAddress: '${{RewardsManager.address}}' - - fn: 'setContractProxy' - id: '0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034' # keccak256('Staking') - contractAddress: '${{L2Staking.address}}' - - fn: 'setContractProxy' - id: '0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247' # keccak256('GraphToken') - contractAddress: '${{L2GraphToken.address}}' - - fn: 'setContractProxy' - id: '0xd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0' # keccak256('GraphTokenGateway') - contractAddress: '${{L2GraphTokenGateway.address}}' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - - fn: 'transferOwnership' - owner: *governor - GraphProxyAdmin: - calls: - - fn: 'transferOwnership' - owner: *governor - ServiceRegistry: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - EpochManager: - proxy: true - init: - controller: '${{Controller.address}}' - lengthInBlocks: 554 # length in hours = lengthInBlocks*13/60/60 (~13 second blocks) - L2GraphToken: - proxy: true - init: - owner: '${{Env.deployer}}' - calls: - - fn: 'addMinter' - minter: '${{RewardsManager.address}}' - - fn: 'renounceMinter' - - fn: 'transferOwnership' - owner: *governor - L2Curation: - proxy: true - init: - controller: '${{Controller.address}}' - curationTokenMaster: '${{GraphCurationToken.address}}' - curationTaxPercentage: 10000 # in parts per million - minimumCurationDeposit: '1' # in wei - calls: - - fn: 'syncAllContracts' - DisputeManager: - proxy: true - init: - controller: '${{Controller.address}}' - arbitrator: *arbitrator - minimumDeposit: '10000000000000000000000' # in wei - fishermanRewardPercentage: 500000 # in parts per million - idxSlashingPercentage: 25000 # in parts per million - qrySlashingPercentage: 25000 # in parts per million - calls: - - fn: 'syncAllContracts' - L2GNS: - proxy: true - init: - controller: '${{Controller.address}}' - subgraphNFT: '${{SubgraphNFT.address}}' - calls: - - fn: 'approveAll' - - fn: 'syncAllContracts' - SubgraphNFT: - init: - governor: '${{Env.deployer}}' - calls: - - fn: 'setTokenDescriptor' - tokenDescriptor: '${{SubgraphNFTDescriptor.address}}' - - fn: 'setMinter' - minter: '${{L2GNS.address}}' - - fn: 'transferOwnership' - owner: *governor - L2Staking: - proxy: true - init: - controller: '${{Controller.address}}' - minimumIndexerStake: '100000000000000000000000' # in wei - thawingPeriod: 6646 # in blocks - protocolPercentage: 10000 # in parts per million - curationPercentage: 100000 # in parts per million - maxAllocationEpochs: 8 # in epochs - delegationUnbondingPeriod: 12 # in epochs - delegationRatio: 16 # delegated stake to indexer stake multiplier - rebateParameters: - alphaNumerator: 100 # alphaNumerator / alphaDenominator - alphaDenominator: 100 # alphaNumerator / alphaDenominator - lambdaNumerator: 60 # lambdaNumerator / lambdaDenominator - lambdaDenominator: 100 # lambdaNumerator / lambdaDenominator - extensionImpl: '${{StakingExtension.address}}' - calls: - - fn: 'setDelegationTaxPercentage' - delegationTaxPercentage: 5000 # parts per million - - fn: 'setSlasher' - slasher: '${{DisputeManager.address}}' - allowed: true - - fn: 'syncAllContracts' - RewardsManager: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'setIssuancePerBlock' - issuancePerBlock: '6036500000000000000' # per block increase of total supply, blocks in a year = 365*60*60*24/12 - - fn: 'setSubgraphAvailabilityOracle' - subgraphAvailabilityOracle: *availabilityOracle - - fn: 'syncAllContracts' - AllocationExchange: - init: - graphToken: '${{L2GraphToken.address}}' - staking: '${{L2Staking.address}}' - governor: *allocationExchangeOwner - authority: *authority - calls: - - fn: 'approveAll' - L2GraphTokenGateway: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian diff --git a/packages/contracts/config/graph.arbitrum-hardhat.yml b/packages/contracts/config/graph.arbitrum-hardhat.yml deleted file mode 100644 index e8f35847f..000000000 --- a/packages/contracts/config/graph.arbitrum-hardhat.yml +++ /dev/null @@ -1,163 +0,0 @@ -general: - arbitrator: &arbitrator '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0' # Arbitration Council - governor: &governor '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b' # Graph Council - authority: &authority '0xE11BA2b4D45Eaed5996Cd0823791E0C93114882d' # Authority that signs payment vouchers - availabilityOracles: &availabilityOracles # Subgraph Availability Oracles - - '0xd03ea8624C8C5987235048901fB614fDcA89b117' - - '0xd03ea8624C8C5987235048901fB614fDcA89b117' - - '0xd03ea8624C8C5987235048901fB614fDcA89b117' - - '0xd03ea8624C8C5987235048901fB614fDcA89b117' - - '0xd03ea8624C8C5987235048901fB614fDcA89b117' - pauseGuardian: &pauseGuardian '0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC' # Protocol pause guardian - allocationExchangeOwner: &allocationExchangeOwner '0x3E5e9111Ae8eB78Fe1CC3bb8915d5D461F3Ef9A9' # Allocation Exchange owner - -contracts: - Controller: - calls: - - fn: 'setContractProxy' - id: '0xe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f' # keccak256('Curation') - contractAddress: '${{L2Curation.address}}' - - fn: 'setContractProxy' - id: '0x39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3' # keccak256('GNS') - contractAddress: '${{L2GNS.address}}' - - fn: 'setContractProxy' - id: '0xf942813d07d17b56de9a9afc8de0ced6e8c053bbfdcc87b7badea4ddcf27c307' # keccak256('DisputeManager') - contractAddress: '${{DisputeManager.address}}' - - fn: 'setContractProxy' - id: '0xc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063' # keccak256('EpochManager') - contractAddress: '${{EpochManager.address}}' - - fn: 'setContractProxy' - id: '0x966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761' # keccak256('RewardsManager') - contractAddress: '${{RewardsManager.address}}' - - fn: 'setContractProxy' - id: '0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034' # keccak256('Staking') - contractAddress: '${{L2Staking.address}}' - - fn: 'setContractProxy' - id: '0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247' # keccak256('GraphToken') - contractAddress: '${{L2GraphToken.address}}' - - fn: 'setContractProxy' - id: '0xd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0' # keccak256('GraphTokenGateway') - contractAddress: '${{L2GraphTokenGateway.address}}' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - - fn: 'transferOwnership' - owner: *governor - GraphProxyAdmin: - calls: - - fn: 'transferOwnership' - owner: *governor - ServiceRegistry: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - EpochManager: - proxy: true - init: - controller: '${{Controller.address}}' - lengthInBlocks: 60 # length in hours = lengthInBlocks*13/60/60 (~13 second blocks) - L2GraphToken: - proxy: true - init: - owner: '${{Env.deployer}}' - calls: - - fn: 'addMinter' - minter: '${{RewardsManager.address}}' - - fn: 'transferOwnership' - owner: *governor - L2Curation: - proxy: true - init: - controller: '${{Controller.address}}' - curationTokenMaster: '${{GraphCurationToken.address}}' - curationTaxPercentage: 0 # in parts per million - minimumCurationDeposit: '1' # in wei - calls: - - fn: 'syncAllContracts' - DisputeManager: - proxy: true - init: - controller: '${{Controller.address}}' - arbitrator: *arbitrator - minimumDeposit: '100000000000000000000' # in wei - fishermanRewardPercentage: 1000 # in parts per million - qrySlashingPercentage: 1000 # in parts per million - idxSlashingPercentage: 100000 # in parts per million - calls: - - fn: 'syncAllContracts' - L2GNS: - proxy: true - init: - controller: '${{Controller.address}}' - subgraphNFT: '${{SubgraphNFT.address}}' - calls: - - fn: 'approveAll' - - fn: 'syncAllContracts' - SubgraphNFT: - init: - governor: '${{Env.deployer}}' - calls: - - fn: 'setTokenDescriptor' - tokenDescriptor: '${{SubgraphNFTDescriptor.address}}' - - fn: 'setMinter' - minter: '${{L2GNS.address}}' - - fn: 'transferOwnership' - owner: *governor - L2Staking: - proxy: true - init: - controller: '${{Controller.address}}' - minimumIndexerStake: '10000000000000000000' # in wei - thawingPeriod: 20 # in blocks - protocolPercentage: 0 # in parts per million - curationPercentage: 0 # in parts per million - maxAllocationEpochs: 5 # in epochs - delegationUnbondingPeriod: 1 # in epochs - delegationRatio: 16 # delegated stake to indexer stake multiplier - rebateParameters: - alphaNumerator: 100 # alphaNumerator / alphaDenominator - alphaDenominator: 100 # alphaNumerator / alphaDenominator - lambdaNumerator: 60 # lambdaNumerator / lambdaDenominator - lambdaDenominator: 100 # lambdaNumerator / lambdaDenominator - extensionImpl: '${{StakingExtension.address}}' - calls: - - fn: 'setDelegationTaxPercentage' - delegationTaxPercentage: 0 # parts per million - - fn: 'setSlasher' - slasher: '${{DisputeManager.address}}' - allowed: true - - fn: 'syncAllContracts' - RewardsManager: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'setIssuancePerBlock' - issuancePerBlock: '114155251141552511415' # per block increase of total supply, blocks in a year = 365*60*60*24/12 - - fn: 'setSubgraphAvailabilityOracle' - subgraphAvailabilityOracle: '${{SubgraphAvailabilityManager.address}}' - - fn: 'syncAllContracts' - AllocationExchange: - init: - graphToken: '${{L2GraphToken.address}}' - staking: '${{L2Staking.address}}' - governor: *allocationExchangeOwner - authority: *authority - calls: - - fn: 'approveAll' - L2GraphTokenGateway: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - SubgraphAvailabilityManager: - init: - governor: *governor - rewardsManager: '${{RewardsManager.address}}' - executionThreshold: 5 - voteTimeLimit: 300 - oracles: *availabilityOracles diff --git a/packages/contracts/config/graph.arbitrum-localhost.yml b/packages/contracts/config/graph.arbitrum-localhost.yml deleted file mode 100644 index b09508fef..000000000 --- a/packages/contracts/config/graph.arbitrum-localhost.yml +++ /dev/null @@ -1,164 +0,0 @@ -general: - arbitrator: &arbitrator '0x4237154FE0510FdE3575656B60c68a01B9dCDdF8' # Arbitration Council - governor: &governor '0x1257227a2ECA34834940110f7B5e341A5143A2c4' # Graph Council - authority: &authority '0x12B8D08b116E1E3cc29eE9Cf42bB0AA8129C3215' # Authority that signs payment vouchers - availabilityOracles: &availabilityOracles # Subgraph Availability Oracles - - '0x7694a48065f063a767a962610C6717c59F36b445' - - '0x7694a48065f063a767a962610C6717c59F36b445' - - '0x7694a48065f063a767a962610C6717c59F36b445' - - '0x7694a48065f063a767a962610C6717c59F36b445' - - '0x7694a48065f063a767a962610C6717c59F36b445' - pauseGuardian: &pauseGuardian '0x601060e0DC5349AA55EC73df5A58cB0FC1cD2e3C' # Protocol pause guardian - allocationExchangeOwner: &allocationExchangeOwner '0xbD38F7b67a591A5cc7D642e1026E5095B819d952' # Allocation Exchange owner - -contracts: - Controller: - calls: - - fn: 'setContractProxy' - id: '0xe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f' # keccak256('Curation') - contractAddress: '${{L2Curation.address}}' - - fn: 'setContractProxy' - id: '0x39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3' # keccak256('GNS') - contractAddress: '${{L2GNS.address}}' - - fn: 'setContractProxy' - id: '0xf942813d07d17b56de9a9afc8de0ced6e8c053bbfdcc87b7badea4ddcf27c307' # keccak256('DisputeManager') - contractAddress: '${{DisputeManager.address}}' - - fn: 'setContractProxy' - id: '0xc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063' # keccak256('EpochManager') - contractAddress: '${{EpochManager.address}}' - - fn: 'setContractProxy' - id: '0x966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761' # keccak256('RewardsManager') - contractAddress: '${{RewardsManager.address}}' - - fn: 'setContractProxy' - id: '0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034' # keccak256('Staking') - contractAddress: '${{L2Staking.address}}' - - fn: 'setContractProxy' - id: '0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247' # keccak256('GraphToken') - contractAddress: '${{L2GraphToken.address}}' - - fn: 'setContractProxy' - id: '0xd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0' # keccak256('GraphTokenGateway') - contractAddress: '${{L2GraphTokenGateway.address}}' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - - fn: 'transferOwnership' - owner: *governor - GraphProxyAdmin: - calls: - - fn: 'transferOwnership' - owner: *governor - ServiceRegistry: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - EpochManager: - proxy: true - init: - controller: '${{Controller.address}}' - lengthInBlocks: 554 # length in hours = lengthInBlocks*13/60/60 (~13 second blocks) - L2GraphToken: - proxy: true - init: - owner: '${{Env.deployer}}' - calls: - - fn: 'addMinter' - minter: '${{RewardsManager.address}}' - - fn: 'renounceMinter' - - fn: 'transferOwnership' - owner: *governor - L2Curation: - proxy: true - init: - controller: '${{Controller.address}}' - curationTokenMaster: '${{GraphCurationToken.address}}' - curationTaxPercentage: 10000 # in parts per million - minimumCurationDeposit: '1' # in wei - calls: - - fn: 'syncAllContracts' - DisputeManager: - proxy: true - init: - controller: '${{Controller.address}}' - arbitrator: *arbitrator - minimumDeposit: '10000000000000000000000' # in wei - fishermanRewardPercentage: 500000 # in parts per million - idxSlashingPercentage: 25000 # in parts per million - qrySlashingPercentage: 25000 # in parts per million - calls: - - fn: 'syncAllContracts' - L2GNS: - proxy: true - init: - controller: '${{Controller.address}}' - subgraphNFT: '${{SubgraphNFT.address}}' - calls: - - fn: 'approveAll' - - fn: 'syncAllContracts' - SubgraphNFT: - init: - governor: '${{Env.deployer}}' - calls: - - fn: 'setTokenDescriptor' - tokenDescriptor: '${{SubgraphNFTDescriptor.address}}' - - fn: 'setMinter' - minter: '${{L2GNS.address}}' - - fn: 'transferOwnership' - owner: *governor - L2Staking: - proxy: true - init: - controller: '${{Controller.address}}' - minimumIndexerStake: '100000000000000000000000' # in wei - thawingPeriod: 6646 # in blocks - protocolPercentage: 10000 # in parts per million - curationPercentage: 100000 # in parts per million - maxAllocationEpochs: 4 # in epochs - delegationUnbondingPeriod: 12 # in epochs - delegationRatio: 16 # delegated stake to indexer stake multiplier - rebateParameters: - alphaNumerator: 100 # alphaNumerator / alphaDenominator - alphaDenominator: 100 # alphaNumerator / alphaDenominator - lambdaNumerator: 60 # lambdaNumerator / lambdaDenominator - lambdaDenominator: 100 # lambdaNumerator / lambdaDenominator - extensionImpl: '${{StakingExtension.address}}' - calls: - - fn: 'setDelegationTaxPercentage' - delegationTaxPercentage: 5000 # parts per million - - fn: 'setSlasher' - slasher: '${{DisputeManager.address}}' - allowed: true - - fn: 'syncAllContracts' - RewardsManager: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'setIssuancePerBlock' - issuancePerBlock: '6036500000000000000' # per block increase of total supply, blocks in a year = 365*60*60*24/12 - - fn: 'setSubgraphAvailabilityOracle' - subgraphAvailabilityOracle: '${{SubgraphAvailabilityManager.address}}' - - fn: 'syncAllContracts' - AllocationExchange: - init: - graphToken: '${{L2GraphToken.address}}' - staking: '${{L2Staking.address}}' - governor: *allocationExchangeOwner - authority: *authority - calls: - - fn: 'approveAll' - L2GraphTokenGateway: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - SubgraphAvailabilityManager: - init: - governor: *governor - rewardsManager: '${{RewardsManager.address}}' - executionThreshold: 5 - voteTimeLimit: 300 - oracles: *availabilityOracles diff --git a/packages/contracts/config/graph.arbitrum-one.yml b/packages/contracts/config/graph.arbitrum-one.yml deleted file mode 100644 index c3796b548..000000000 --- a/packages/contracts/config/graph.arbitrum-one.yml +++ /dev/null @@ -1,152 +0,0 @@ -general: - arbitrator: &arbitrator '0x113DC95e796836b8F0Fa71eE7fB42f221740c3B0' # Arbitration Council - governor: &governor '0x8C6de8F8D562f3382417340A6994601eE08D3809' # Graph Council - authority: &authority '0x4a06858f104B2aB1e1185AB7E09F7B5d3b700479' # Authority that signs payment vouchers - availabilityOracle: &availabilityOracle '0x1BEB2266f264Cebd9C6FBE1ceB394a8d944401c1' # Subgraph Availability Oracle - pauseGuardian: &pauseGuardian '0xB0aD33a21b98bCA1761729A105e2E34e27153aAE' # Protocol pause guardian - allocationExchangeOwner: &allocationExchangeOwner '0x270Ea4ea9e8A699f8fE54515E3Bb2c418952623b' # Allocation Exchange owner - -contracts: - Controller: - calls: - - fn: 'setContractProxy' - id: '0xe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f' # keccak256('Curation') - contractAddress: '${{L2Curation.address}}' - - fn: 'setContractProxy' - id: '0x39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3' # keccak256('GNS') - contractAddress: '${{L2GNS.address}}' - - fn: 'setContractProxy' - id: '0xf942813d07d17b56de9a9afc8de0ced6e8c053bbfdcc87b7badea4ddcf27c307' # keccak256('DisputeManager') - contractAddress: '${{DisputeManager.address}}' - - fn: 'setContractProxy' - id: '0xc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063' # keccak256('EpochManager') - contractAddress: '${{EpochManager.address}}' - - fn: 'setContractProxy' - id: '0x966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761' # keccak256('RewardsManager') - contractAddress: '${{RewardsManager.address}}' - - fn: 'setContractProxy' - id: '0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034' # keccak256('Staking') - contractAddress: '${{L2Staking.address}}' - - fn: 'setContractProxy' - id: '0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247' # keccak256('GraphToken') - contractAddress: '${{L2GraphToken.address}}' - - fn: 'setContractProxy' - id: '0xd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0' # keccak256('GraphTokenGateway') - contractAddress: '${{L2GraphTokenGateway.address}}' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - - fn: 'transferOwnership' - owner: *governor - GraphProxyAdmin: - calls: - - fn: 'transferOwnership' - owner: *governor - ServiceRegistry: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - EpochManager: - proxy: true - init: - controller: '${{Controller.address}}' - lengthInBlocks: 6646 # length in hours = lengthInBlocks*13/60/60 (~13 second blocks) - L2GraphToken: - proxy: true - init: - owner: '${{Env.deployer}}' - calls: - - fn: 'addMinter' - minter: '${{RewardsManager.address}}' - - fn: 'renounceMinter' - - fn: 'transferOwnership' - owner: *governor - L2Curation: - proxy: true - init: - controller: '${{Controller.address}}' - curationTokenMaster: '${{GraphCurationToken.address}}' - curationTaxPercentage: 10000 # in parts per million - minimumCurationDeposit: '1' # in wei - calls: - - fn: 'syncAllContracts' - DisputeManager: - proxy: true - init: - controller: '${{Controller.address}}' - arbitrator: *arbitrator - minimumDeposit: '10000000000000000000000' # in wei - fishermanRewardPercentage: 500000 # in parts per million - idxSlashingPercentage: 25000 # in parts per million - qrySlashingPercentage: 25000 # in parts per million - calls: - - fn: 'syncAllContracts' - L2GNS: - proxy: true - init: - controller: '${{Controller.address}}' - subgraphNFT: '${{SubgraphNFT.address}}' - calls: - - fn: 'approveAll' - - fn: 'syncAllContracts' - SubgraphNFT: - init: - governor: '${{Env.deployer}}' - calls: - - fn: 'setTokenDescriptor' - tokenDescriptor: '${{SubgraphNFTDescriptor.address}}' - - fn: 'setMinter' - minter: '${{L2GNS.address}}' - - fn: 'transferOwnership' - owner: *governor - L2Staking: - proxy: true - init: - controller: '${{Controller.address}}' - minimumIndexerStake: '100000000000000000000000' # in wei - thawingPeriod: 186092 # in blocks - protocolPercentage: 10000 # in parts per million - curationPercentage: 100000 # in parts per million - maxAllocationEpochs: 28 # in epochs - delegationUnbondingPeriod: 28 # in epochs - delegationRatio: 16 # delegated stake to indexer stake multiplier - rebateParameters: - alphaNumerator: 100 # alphaNumerator / alphaDenominator - alphaDenominator: 100 # alphaNumerator / alphaDenominator - lambdaNumerator: 60 # lambdaNumerator / lambdaDenominator - lambdaDenominator: 100 # lambdaNumerator / lambdaDenominator - extensionImpl: '${{StakingExtension.address}}' - calls: - - fn: 'setDelegationTaxPercentage' - delegationTaxPercentage: 5000 # parts per million - - fn: 'setSlasher' - slasher: '${{DisputeManager.address}}' - allowed: true - - fn: 'syncAllContracts' - RewardsManager: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'setIssuancePerBlock' - issuancePerBlock: '6036500000000000000' # per block increase of total supply, blocks in a year = 365*60*60*24/12 - - fn: 'setSubgraphAvailabilityOracle' - subgraphAvailabilityOracle: *availabilityOracle - - fn: 'syncAllContracts' - AllocationExchange: - init: - graphToken: '${{L2GraphToken.address}}' - staking: '${{L2Staking.address}}' - governor: *allocationExchangeOwner - authority: *authority - calls: - - fn: 'approveAll' - L2GraphTokenGateway: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian diff --git a/packages/contracts/config/graph.arbitrum-sepolia.yml b/packages/contracts/config/graph.arbitrum-sepolia.yml deleted file mode 100644 index 4d4c0785e..000000000 --- a/packages/contracts/config/graph.arbitrum-sepolia.yml +++ /dev/null @@ -1,163 +0,0 @@ -general: - arbitrator: &arbitrator '0x1726A5d52e279d02ff4732eCeB2D67BFE5Add328' # EOA (TODO: update to a multisig) - governor: &governor '0x72ee30d43Fb5A90B3FE983156C5d2fBE6F6d07B3' # EOA (TODO: update to a multisig) - authority: &authority '0x49D4CFC037430cA9355B422bAeA7E9391e1d3215' # Authority that signs payment vouchers - availabilityOracles: &availabilityOracles # Array of Subgraph Availability Oracles - - '0x5e4e823Ed094c035133eEC5Ec0d08ae1Af04e9Fa' - - '0x5aeE4c46cF9260E85E630ca7d9D757D5D5DbaFD6' - - '0x7369Cf2a917296c36f506144f3dE552403d1e1f1' - - '0x1e1f84c07e0471fc979f6f08228b0bd34cda9e54' - - '0x711aEA1f358DFAf74D34B4B525F9190e631F406C' - pauseGuardian: &pauseGuardian '0xa0444508232dA3FA6C2f96a5f105f3f0cc0d20D7' # Protocol pause guardian - allocationExchangeOwner: &allocationExchangeOwner '0x72ee30d43Fb5A90B3FE983156C5d2fBE6F6d07B3' # Allocation Exchange owner - -contracts: - Controller: - calls: - - fn: 'setContractProxy' - id: '0xe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f' # keccak256('Curation') - contractAddress: '${{L2Curation.address}}' - - fn: 'setContractProxy' - id: '0x39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3' # keccak256('GNS') - contractAddress: '${{L2GNS.address}}' - - fn: 'setContractProxy' - id: '0xf942813d07d17b56de9a9afc8de0ced6e8c053bbfdcc87b7badea4ddcf27c307' # keccak256('DisputeManager') - contractAddress: '${{DisputeManager.address}}' - - fn: 'setContractProxy' - id: '0xc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063' # keccak256('EpochManager') - contractAddress: '${{EpochManager.address}}' - - fn: 'setContractProxy' - id: '0x966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761' # keccak256('RewardsManager') - contractAddress: '${{RewardsManager.address}}' - - fn: 'setContractProxy' - id: '0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034' # keccak256('Staking') - contractAddress: '${{L2Staking.address}}' - - fn: 'setContractProxy' - id: '0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247' # keccak256('GraphToken') - contractAddress: '${{L2GraphToken.address}}' - - fn: 'setContractProxy' - id: '0xd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0' # keccak256('GraphTokenGateway') - contractAddress: '${{L2GraphTokenGateway.address}}' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - - fn: 'transferOwnership' - owner: *governor - GraphProxyAdmin: - calls: - - fn: 'transferOwnership' - owner: *governor - ServiceRegistry: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - EpochManager: - proxy: true - init: - controller: '${{Controller.address}}' - lengthInBlocks: 554 # length in hours = lengthInBlocks*13/60/60 (~13 second blocks) - L2GraphToken: - proxy: true - init: - owner: '${{Env.deployer}}' - calls: - - fn: 'addMinter' - minter: '${{RewardsManager.address}}' - - fn: 'transferOwnership' - owner: *governor - L2Curation: - proxy: true - init: - controller: '${{Controller.address}}' - curationTokenMaster: '${{GraphCurationToken.address}}' - curationTaxPercentage: 10000 # in parts per million - minimumCurationDeposit: '1' # in wei - calls: - - fn: 'syncAllContracts' - DisputeManager: - proxy: true - init: - controller: '${{Controller.address}}' - arbitrator: *arbitrator - minimumDeposit: '10000000000000000000000' # in wei - fishermanRewardPercentage: 500000 # in parts per million - idxSlashingPercentage: 25000 # in parts per million - qrySlashingPercentage: 25000 # in parts per million - calls: - - fn: 'syncAllContracts' - L2GNS: - proxy: true - init: - controller: '${{Controller.address}}' - subgraphNFT: '${{SubgraphNFT.address}}' - calls: - - fn: 'approveAll' - - fn: 'syncAllContracts' - SubgraphNFT: - init: - governor: '${{Env.deployer}}' - calls: - - fn: 'setTokenDescriptor' - tokenDescriptor: '${{SubgraphNFTDescriptor.address}}' - - fn: 'setMinter' - minter: '${{L2GNS.address}}' - - fn: 'transferOwnership' - owner: *governor - L2Staking: - proxy: true - init: - controller: '${{Controller.address}}' - minimumIndexerStake: '100000000000000000000000' # in wei - thawingPeriod: 6646 # in blocks - protocolPercentage: 10000 # in parts per million - curationPercentage: 100000 # in parts per million - maxAllocationEpochs: 8 # in epochs - delegationUnbondingPeriod: 12 # in epochs - delegationRatio: 16 # delegated stake to indexer stake multiplier - rebateParameters: - alphaNumerator: 100 # alphaNumerator / alphaDenominator - alphaDenominator: 100 # alphaNumerator / alphaDenominator - lambdaNumerator: 60 # lambdaNumerator / lambdaDenominator - lambdaDenominator: 100 # lambdaNumerator / lambdaDenominator - extensionImpl: '${{StakingExtension.address}}' - calls: - - fn: 'setDelegationTaxPercentage' - delegationTaxPercentage: 5000 # parts per million - - fn: 'setSlasher' - slasher: '${{DisputeManager.address}}' - allowed: true - - fn: 'syncAllContracts' - RewardsManager: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'setIssuancePerBlock' - issuancePerBlock: '6036500000000000000' # per block increase of total supply, blocks in a year = 365*60*60*24/12 - - fn: 'setSubgraphAvailabilityOracle' - subgraphAvailabilityOracle: '${{SubgraphAvailabilityManager.address}}' - - fn: 'syncAllContracts' - AllocationExchange: - init: - graphToken: '${{L2GraphToken.address}}' - staking: '${{L2Staking.address}}' - governor: *allocationExchangeOwner - authority: *authority - calls: - - fn: 'approveAll' - L2GraphTokenGateway: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - SubgraphAvailabilityManager: - init: - governor: *governor - rewardsManager: '${{RewardsManager.address}}' - executionThreshold: 5 - voteTimeLimit: 300 - oracles: *availabilityOracles diff --git a/packages/contracts/config/graph.goerli.yml b/packages/contracts/config/graph.goerli.yml deleted file mode 100644 index f4128f936..000000000 --- a/packages/contracts/config/graph.goerli.yml +++ /dev/null @@ -1,161 +0,0 @@ -general: - arbitrator: &arbitrator '0xFD01aa87BeB04D0ac764FC298aCFd05FfC5439cD' # Arbitration Council - governor: &governor '0xf1135bFF22512FF2A585b8d4489426CE660f204c' # Graph Council - authority: &authority '0x52e498aE9B8A5eE2A5Cd26805F06A9f29A7F489F' # Authority that signs payment vouchers - availabilityOracle: &availabilityOracle '0xDC6785e39Cba34A6d258148e3E83E24285118796' # Subgraph Availability Oracle - pauseGuardian: &pauseGuardian '0x6855D551CaDe60754D145fb5eDCD90912D860262' # Protocol pause guardian - allocationExchangeOwner: &allocationExchangeOwner '0xf1135bFF22512FF2A585b8d4489426CE660f204c' # Allocation Exchange owner - -contracts: - Controller: - calls: - - fn: 'setContractProxy' - id: '0xe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f' # keccak256('Curation') - contractAddress: '${{Curation.address}}' - - fn: 'setContractProxy' - id: '0x39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3' # keccak256('GNS') - contractAddress: '${{L1GNS.address}}' - - fn: 'setContractProxy' - id: '0xf942813d07d17b56de9a9afc8de0ced6e8c053bbfdcc87b7badea4ddcf27c307' # keccak256('DisputeManager') - contractAddress: '${{DisputeManager.address}}' - - fn: 'setContractProxy' - id: '0xc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063' # keccak256('EpochManager') - contractAddress: '${{EpochManager.address}}' - - fn: 'setContractProxy' - id: '0x966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761' # keccak256('RewardsManager') - contractAddress: '${{RewardsManager.address}}' - - fn: 'setContractProxy' - id: '0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034' # keccak256('Staking') - contractAddress: '${{L1Staking.address}}' - - fn: 'setContractProxy' - id: '0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247' # keccak256('GraphToken') - contractAddress: '${{GraphToken.address}}' - - fn: 'setContractProxy' - id: '0xd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0' # keccak256('GraphTokenGateway') - contractAddress: '${{L1GraphTokenGateway.address}}' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - - fn: 'transferOwnership' - owner: *governor - GraphProxyAdmin: - calls: - - fn: 'transferOwnership' - owner: *governor - ServiceRegistry: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - EpochManager: - proxy: true - init: - controller: '${{Controller.address}}' - lengthInBlocks: 554 # length in hours = lengthInBlocks*13/60/60 (~13 second blocks) - GraphToken: - init: - initialSupply: '10000000000000000000000000000' # in wei - calls: - - fn: 'addMinter' - minter: '${{RewardsManager.address}}' - - fn: 'addMinter' - minter: '${{L1GraphTokenGateway.address}}' - - fn: 'renounceMinter' - - fn: 'transferOwnership' - owner: *governor - Curation: - proxy: true - init: - controller: '${{Controller.address}}' - bondingCurve: '${{BancorFormula.address}}' - curationTokenMaster: '${{GraphCurationToken.address}}' - reserveRatio: 500000 # in parts per million - curationTaxPercentage: 10000 # in parts per million - minimumCurationDeposit: '1000000000000000000' # in wei - calls: - - fn: 'syncAllContracts' - DisputeManager: - proxy: true - init: - controller: '${{Controller.address}}' - arbitrator: *arbitrator - minimumDeposit: '10000000000000000000000' # in wei - fishermanRewardPercentage: 500000 # in parts per million - idxSlashingPercentage: 25000 # in parts per million - qrySlashingPercentage: 25000 # in parts per million - calls: - - fn: 'syncAllContracts' - L1GNS: - proxy: true - init: - controller: '${{Controller.address}}' - subgraphNFT: '${{SubgraphNFT.address}}' - calls: - - fn: 'approveAll' - - fn: 'syncAllContracts' - SubgraphNFT: - init: - governor: '${{Env.deployer}}' - calls: - - fn: 'setTokenDescriptor' - tokenDescriptor: '${{SubgraphNFTDescriptor.address}}' - - fn: 'setMinter' - minter: '${{L1GNS.address}}' - - fn: 'transferOwnership' - owner: *governor - L1Staking: - proxy: true - init: - controller: '${{Controller.address}}' - minimumIndexerStake: '100000000000000000000000' # in wei - thawingPeriod: 6646 # in blocks - protocolPercentage: 10000 # in parts per million - curationPercentage: 100000 # in parts per million - maxAllocationEpochs: 4 # in epochs - delegationUnbondingPeriod: 12 # in epochs - delegationRatio: 16 # delegated stake to indexer stake multiplier - rebateParameters: - alphaNumerator: 100 # alphaNumerator / alphaDenominator - alphaDenominator: 100 # alphaNumerator / alphaDenominator - lambdaNumerator: 60 # lambdaNumerator / lambdaDenominator - lambdaDenominator: 100 # lambdaNumerator / lambdaDenominator - extensionImpl: '${{StakingExtension.address}}' - calls: - - fn: 'setDelegationTaxPercentage' - delegationTaxPercentage: 5000 # parts per million - - fn: 'setSlasher' - slasher: '${{DisputeManager.address}}' - allowed: true - - fn: 'syncAllContracts' - RewardsManager: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'setIssuancePerBlock' - issuancePerBlock: '114693500000000000000' # per block increase of total supply, blocks in a year = 365*60*60*24/12 - - fn: 'setSubgraphAvailabilityOracle' - subgraphAvailabilityOracle: *availabilityOracle - - fn: 'syncAllContracts' - AllocationExchange: - init: - graphToken: '${{GraphToken.address}}' - staking: '${{L1Staking.address}}' - governor: *allocationExchangeOwner - authority: *authority - calls: - - fn: 'approveAll' - L1GraphTokenGateway: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - BridgeEscrow: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' diff --git a/packages/contracts/config/graph.hardhat.yml b/packages/contracts/config/graph.hardhat.yml deleted file mode 100644 index c5e15f2dd..000000000 --- a/packages/contracts/config/graph.hardhat.yml +++ /dev/null @@ -1,160 +0,0 @@ -general: - arbitrator: &arbitrator '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0' # Arbitration Council - governor: &governor '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b' # Governor Council - authority: &authority '0xE11BA2b4D45Eaed5996Cd0823791E0C93114882d' # Authority that signs payment vouchers - availabilityOracle: &availabilityOracle '0xd03ea8624C8C5987235048901fB614fDcA89b117' # Subgraph Availability Oracle - pauseGuardian: &pauseGuardian '0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC' # Protocol pause guardian - allocationExchangeOwner: &allocationExchangeOwner '0x3E5e9111Ae8eB78Fe1CC3bb8915d5D461F3Ef9A9' # Allocation Exchange owner - -contracts: - Controller: - calls: - - fn: 'setContractProxy' - id: '0xe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f' # keccak256('Curation') - contractAddress: '${{Curation.address}}' - - fn: 'setContractProxy' - id: '0x39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3' # keccak256('GNS') - contractAddress: '${{L1GNS.address}}' - - fn: 'setContractProxy' - id: '0xf942813d07d17b56de9a9afc8de0ced6e8c053bbfdcc87b7badea4ddcf27c307' # keccak256('DisputeManager') - contractAddress: '${{DisputeManager.address}}' - - fn: 'setContractProxy' - id: '0xc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063' # keccak256('EpochManager') - contractAddress: '${{EpochManager.address}}' - - fn: 'setContractProxy' - id: '0x966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761' # keccak256('RewardsManager') - contractAddress: '${{RewardsManager.address}}' - - fn: 'setContractProxy' - id: '0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034' # keccak256('Staking') - contractAddress: '${{L1Staking.address}}' - - fn: 'setContractProxy' - id: '0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247' # keccak256('GraphToken') - contractAddress: '${{GraphToken.address}}' - - fn: 'setContractProxy' - id: '0xd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0' # keccak256('GraphTokenGateway') - contractAddress: '${{L1GraphTokenGateway.address}}' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - - fn: 'transferOwnership' - owner: *governor - GraphProxyAdmin: - calls: - - fn: 'transferOwnership' - owner: *governor - ServiceRegistry: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - EpochManager: - proxy: true - init: - controller: '${{Controller.address}}' - lengthInBlocks: 60 # length in hours = lengthInBlocks*13/60/60 (~13 second blocks) - GraphToken: - init: - initialSupply: '10000000000000000000000000000' # in wei - calls: - - fn: 'addMinter' - minter: '${{RewardsManager.address}}' - - fn: 'addMinter' - minter: '${{L1GraphTokenGateway.address}}' - - fn: 'transferOwnership' - owner: *governor - Curation: - proxy: true - init: - controller: '${{Controller.address}}' - bondingCurve: '${{BancorFormula.address}}' - curationTokenMaster: '${{GraphCurationToken.address}}' - reserveRatio: 500000 # in parts per million - curationTaxPercentage: 0 # in parts per million - minimumCurationDeposit: '100000000000000000000' # in wei - calls: - - fn: 'syncAllContracts' - DisputeManager: - proxy: true - init: - controller: '${{Controller.address}}' - arbitrator: *arbitrator - minimumDeposit: '100000000000000000000' # in wei - fishermanRewardPercentage: 1000 # in parts per million - qrySlashingPercentage: 1000 # in parts per million - idxSlashingPercentage: 100000 # in parts per million - calls: - - fn: 'syncAllContracts' - L1GNS: - proxy: true - init: - controller: '${{Controller.address}}' - subgraphNFT: '${{SubgraphNFT.address}}' - calls: - - fn: 'approveAll' - - fn: 'syncAllContracts' - SubgraphNFT: - init: - governor: '${{Env.deployer}}' - calls: - - fn: 'setTokenDescriptor' - tokenDescriptor: '${{SubgraphNFTDescriptor.address}}' - - fn: 'setMinter' - minter: '${{L1GNS.address}}' - - fn: 'transferOwnership' - owner: *governor - L1Staking: - proxy: true - init: - controller: '${{Controller.address}}' - minimumIndexerStake: '10000000000000000000' # in wei - thawingPeriod: 20 # in blocks - protocolPercentage: 0 # in parts per million - curationPercentage: 0 # in parts per million - maxAllocationEpochs: 5 # in epochs - delegationUnbondingPeriod: 1 # in epochs - delegationRatio: 16 # delegated stake to indexer stake multiplier - rebateParameters: - alphaNumerator: 100 # alphaNumerator / alphaDenominator - alphaDenominator: 100 # alphaNumerator / alphaDenominator - lambdaNumerator: 60 # lambdaNumerator / lambdaDenominator - lambdaDenominator: 100 # lambdaNumerator / lambdaDenominator - extensionImpl: '${{StakingExtension.address}}' - calls: - - fn: 'setDelegationTaxPercentage' - delegationTaxPercentage: 0 # parts per million - - fn: 'setSlasher' - slasher: '${{DisputeManager.address}}' - allowed: true - - fn: 'syncAllContracts' - RewardsManager: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'setIssuancePerBlock' - issuancePerBlock: '114155251141552511415' # per block increase of total supply, blocks in a year = 365*60*60*24/12 - - fn: 'setSubgraphAvailabilityOracle' - subgraphAvailabilityOracle: *availabilityOracle - - fn: 'syncAllContracts' - AllocationExchange: - init: - graphToken: '${{GraphToken.address}}' - staking: '${{L1Staking.address}}' - governor: *allocationExchangeOwner - authority: *authority - calls: - - fn: 'approveAll' - L1GraphTokenGateway: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - BridgeEscrow: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' diff --git a/packages/contracts/config/graph.localhost.yml b/packages/contracts/config/graph.localhost.yml deleted file mode 100644 index 0a2b2f75d..000000000 --- a/packages/contracts/config/graph.localhost.yml +++ /dev/null @@ -1,161 +0,0 @@ -general: - arbitrator: &arbitrator '0xFFcf8FDEE72ac11b5c542428B35EEF5769C409f0' # Arbitration Council - governor: &governor '0x22d491Bde2303f2f43325b2108D26f1eAbA1e32b' # Governor Council - authority: &authority '0xE11BA2b4D45Eaed5996Cd0823791E0C93114882d' # Authority that signs payment vouchers - availabilityOracle: &availabilityOracle '0xd03ea8624C8C5987235048901fB614fDcA89b117' # Subgraph Availability Oracle - pauseGuardian: &pauseGuardian '0x95cED938F7991cd0dFcb48F0a06a40FA1aF46EBC' # Protocol pause guardian - allocationExchangeOwner: &allocationExchangeOwner '0x3E5e9111Ae8eB78Fe1CC3bb8915d5D461F3Ef9A9' # Allocation Exchange owner - -contracts: - Controller: - calls: - - fn: 'setContractProxy' - id: '0xe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f' # keccak256('Curation') - contractAddress: '${{Curation.address}}' - - fn: 'setContractProxy' - id: '0x39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3' # keccak256('GNS') - contractAddress: '${{L1GNS.address}}' - - fn: 'setContractProxy' - id: '0xf942813d07d17b56de9a9afc8de0ced6e8c053bbfdcc87b7badea4ddcf27c307' # keccak256('DisputeManager') - contractAddress: '${{DisputeManager.address}}' - - fn: 'setContractProxy' - id: '0xc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063' # keccak256('EpochManager') - contractAddress: '${{EpochManager.address}}' - - fn: 'setContractProxy' - id: '0x966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761' # keccak256('RewardsManager') - contractAddress: '${{RewardsManager.address}}' - - fn: 'setContractProxy' - id: '0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034' # keccak256('Staking') - contractAddress: '${{L1Staking.address}}' - - fn: 'setContractProxy' - id: '0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247' # keccak256('GraphToken') - contractAddress: '${{GraphToken.address}}' - - fn: 'setContractProxy' - id: '0xd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0' # keccak256('GraphTokenGateway') - contractAddress: '${{L1GraphTokenGateway.address}}' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - - fn: 'transferOwnership' - owner: *governor - GraphProxyAdmin: - calls: - - fn: 'transferOwnership' - owner: *governor - ServiceRegistry: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - EpochManager: - proxy: true - init: - controller: '${{Controller.address}}' - lengthInBlocks: 554 # length in hours = lengthInBlocks*13/60/60 (~13 second blocks) - GraphToken: - init: - initialSupply: '10000000000000000000000000000' # in wei - calls: - - fn: 'addMinter' - minter: '${{RewardsManager.address}}' - - fn: 'addMinter' - minter: '${{L1GraphTokenGateway.address}}' - - fn: 'renounceMinter' - - fn: 'transferOwnership' - owner: *governor - Curation: - proxy: true - init: - controller: '${{Controller.address}}' - bondingCurve: '${{BancorFormula.address}}' - curationTokenMaster: '${{GraphCurationToken.address}}' - reserveRatio: 500000 # in parts per million - curationTaxPercentage: 10000 # in parts per million - minimumCurationDeposit: '1000000000000000000' # in wei - calls: - - fn: 'syncAllContracts' - DisputeManager: - proxy: true - init: - controller: '${{Controller.address}}' - arbitrator: *arbitrator - minimumDeposit: '10000000000000000000000' # in wei - fishermanRewardPercentage: 500000 # in parts per million - idxSlashingPercentage: 25000 # in parts per million - qrySlashingPercentage: 25000 # in parts per million - calls: - - fn: 'syncAllContracts' - L1GNS: - proxy: true - init: - controller: '${{Controller.address}}' - subgraphNFT: '${{SubgraphNFT.address}}' - calls: - - fn: 'approveAll' - - fn: 'syncAllContracts' - SubgraphNFT: - init: - governor: '${{Env.deployer}}' - calls: - - fn: 'setTokenDescriptor' - tokenDescriptor: '${{SubgraphNFTDescriptor.address}}' - - fn: 'setMinter' - minter: '${{L1GNS.address}}' - - fn: 'transferOwnership' - owner: *governor - L1Staking: - proxy: true - init: - controller: '${{Controller.address}}' - minimumIndexerStake: '100000000000000000000000' # in wei - thawingPeriod: 6646 # in blocks - protocolPercentage: 10000 # in parts per million - curationPercentage: 100000 # in parts per million - maxAllocationEpochs: 4 # in epochs - delegationUnbondingPeriod: 12 # in epochs - delegationRatio: 16 # delegated stake to indexer stake multiplier - rebateParameters: - alphaNumerator: 100 # alphaNumerator / alphaDenominator - alphaDenominator: 100 # alphaNumerator / alphaDenominator - lambdaNumerator: 60 # lambdaNumerator / lambdaDenominator - lambdaDenominator: 100 # lambdaNumerator / lambdaDenominator - extensionImpl: '${{StakingExtension.address}}' - calls: - - fn: 'setDelegationTaxPercentage' - delegationTaxPercentage: 5000 # parts per million - - fn: 'setSlasher' - slasher: '${{DisputeManager.address}}' - allowed: true - - fn: 'syncAllContracts' - RewardsManager: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'setIssuancePerBlock' - issuancePerBlock: '114693500000000000000' # per block increase of total supply, blocks in a year = 365*60*60*24/12 - - fn: 'setSubgraphAvailabilityOracle' - subgraphAvailabilityOracle: *availabilityOracle - - fn: 'syncAllContracts' - AllocationExchange: - init: - graphToken: '${{GraphToken.address}}' - staking: '${{L1Staking.address}}' - governor: *allocationExchangeOwner - authority: *authority - calls: - - fn: 'approveAll' - L1GraphTokenGateway: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - BridgeEscrow: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' diff --git a/packages/contracts/config/graph.mainnet.yml b/packages/contracts/config/graph.mainnet.yml deleted file mode 100644 index 93aefea25..000000000 --- a/packages/contracts/config/graph.mainnet.yml +++ /dev/null @@ -1,161 +0,0 @@ -general: - arbitrator: &arbitrator '0xE1FDD398329C6b74C14cf19100316f0826a492d3' # Arbitration Council - governor: &governor '0x48301Fe520f72994d32eAd72E2B6A8447873CF50' # Graph Council - authority: &authority '0xF994fB0f5c06B31E364B868886140cC30A7fcF15' # Authority that signs payment vouchers - availabilityOracle: &availabilityOracle '0xE24f399999D47D276Da88FAa7646e2C597822333' # Subgraph Availability Oracle - pauseGuardian: &pauseGuardian '0x8290362Aba20D17c51995085369E001Bad99B21c' # Protocol pause guardian - allocationExchangeOwner: &allocationExchangeOwner '0x74Db79268e63302d3FC69FB5a7627F7454a41732' # Allocation Exchange owner - -contracts: - Controller: - calls: - - fn: 'setContractProxy' - id: '0xe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f' # keccak256('Curation') - contractAddress: '${{Curation.address}}' - - fn: 'setContractProxy' - id: '0x39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3' # keccak256('GNS') - contractAddress: '${{L1GNS.address}}' - - fn: 'setContractProxy' - id: '0xf942813d07d17b56de9a9afc8de0ced6e8c053bbfdcc87b7badea4ddcf27c307' # keccak256('DisputeManager') - contractAddress: '${{DisputeManager.address}}' - - fn: 'setContractProxy' - id: '0xc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063' # keccak256('EpochManager') - contractAddress: '${{EpochManager.address}}' - - fn: 'setContractProxy' - id: '0x966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761' # keccak256('RewardsManager') - contractAddress: '${{RewardsManager.address}}' - - fn: 'setContractProxy' - id: '0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034' # keccak256('Staking') - contractAddress: '${{L1Staking.address}}' - - fn: 'setContractProxy' - id: '0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247' # keccak256('GraphToken') - contractAddress: '${{GraphToken.address}}' - - fn: 'setContractProxy' - id: '0xd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0' # keccak256('GraphTokenGateway') - contractAddress: '${{L1GraphTokenGateway.address}}' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - - fn: 'transferOwnership' - owner: *governor - GraphProxyAdmin: - calls: - - fn: 'transferOwnership' - owner: *governor - ServiceRegistry: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - EpochManager: - proxy: true - init: - controller: '${{Controller.address}}' - lengthInBlocks: 6646 # length in hours = lengthInBlocks*13/60/60 (~13 second blocks) - GraphToken: - init: - initialSupply: '10000000000000000000000000000' # in wei - calls: - - fn: 'addMinter' - minter: '${{RewardsManager.address}}' - - fn: 'addMinter' - minter: '${{L1GraphTokenGateway.address}}' - - fn: 'renounceMinter' - - fn: 'transferOwnership' - owner: *governor - Curation: - proxy: true - init: - controller: '${{Controller.address}}' - bondingCurve: '${{BancorFormula.address}}' - curationTokenMaster: '${{GraphCurationToken.address}}' - reserveRatio: 500000 # in parts per million - curationTaxPercentage: 10000 # in parts per million - minimumCurationDeposit: '1000000000000000000' # in wei - calls: - - fn: 'syncAllContracts' - DisputeManager: - proxy: true - init: - controller: '${{Controller.address}}' - arbitrator: *arbitrator - minimumDeposit: '10000000000000000000000' # in wei - fishermanRewardPercentage: 500000 # in parts per million - idxSlashingPercentage: 25000 # in parts per million - qrySlashingPercentage: 25000 # in parts per million - calls: - - fn: 'syncAllContracts' - L1GNS: - proxy: true - init: - controller: '${{Controller.address}}' - subgraphNFT: '${{SubgraphNFT.address}}' - calls: - - fn: 'approveAll' - - fn: 'syncAllContracts' - SubgraphNFT: - init: - governor: '${{Env.deployer}}' - calls: - - fn: 'setTokenDescriptor' - tokenDescriptor: '${{SubgraphNFTDescriptor.address}}' - - fn: 'setMinter' - minter: '${{L1GNS.address}}' - - fn: 'transferOwnership' - owner: *governor - L1Staking: - proxy: true - init: - controller: '${{Controller.address}}' - minimumIndexerStake: '100000000000000000000000' # in wei - thawingPeriod: 186092 # in blocks - protocolPercentage: 10000 # in parts per million - curationPercentage: 100000 # in parts per million - maxAllocationEpochs: 28 # in epochs - delegationUnbondingPeriod: 28 # in epochs - delegationRatio: 16 # delegated stake to indexer stake multiplier - rebateParameters: - alphaNumerator: 100 # alphaNumerator / alphaDenominator - alphaDenominator: 100 # alphaNumerator / alphaDenominator - lambdaNumerator: 60 # lambdaNumerator / lambdaDenominator - lambdaDenominator: 100 # lambdaNumerator / lambdaDenominator - extensionImpl: '${{StakingExtension.address}}' - calls: - - fn: 'setDelegationTaxPercentage' - delegationTaxPercentage: 5000 # parts per million - - fn: 'setSlasher' - slasher: '${{DisputeManager.address}}' - allowed: true - - fn: 'syncAllContracts' - RewardsManager: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'setIssuancePerBlock' - issuancePerBlock: '114693500000000000000' # per block increase of total supply, blocks in a year = 365*60*60*24/12 - - fn: 'setSubgraphAvailabilityOracle' - subgraphAvailabilityOracle: *availabilityOracle - - fn: 'syncAllContracts' - AllocationExchange: - init: - graphToken: '${{GraphToken.address}}' - staking: '${{L1Staking.address}}' - governor: *allocationExchangeOwner - authority: *authority - calls: - - fn: 'approveAll' - L1GraphTokenGateway: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - BridgeEscrow: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' diff --git a/packages/contracts/config/graph.sepolia.yml b/packages/contracts/config/graph.sepolia.yml deleted file mode 100644 index f73bca3d7..000000000 --- a/packages/contracts/config/graph.sepolia.yml +++ /dev/null @@ -1,161 +0,0 @@ -general: - arbitrator: &arbitrator '0xd6ff9e98F0Fd99ccB658832F586e23F4D8Cb8Bad' # Arbitration Council - governor: &governor '0x4EBf30832eC2db76aE228D5d239083B59f530d1f' # Graph Council - authority: &authority '0x840daec5dF962D49cf2EFd789c4E40A7b7e0117D' # Authority that signs payment vouchers - availabilityOracle: &availabilityOracle '0x840daec5dF962D49cf2EFd789c4E40A7b7e0117D' # Subgraph Availability Oracle - pauseGuardian: &pauseGuardian '0x382688E15Cc894D04cf3313b26a4F2c93C8fDe06' # Protocol pause guardian - allocationExchangeOwner: &allocationExchangeOwner '0x4EBf30832eC2db76aE228D5d239083B59f530d1f' # Allocation Exchange owner - -contracts: - Controller: - calls: - - fn: 'setContractProxy' - id: '0xe6876326c1291dfcbbd3864a6816d698cd591defc7aa2153d7f9c4c04016c89f' # keccak256('Curation') - contractAddress: '${{Curation.address}}' - - fn: 'setContractProxy' - id: '0x39605a6c26a173774ca666c67ef70cf491880e5d3d6d0ca66ec0a31034f15ea3' # keccak256('GNS') - contractAddress: '${{L1GNS.address}}' - - fn: 'setContractProxy' - id: '0xf942813d07d17b56de9a9afc8de0ced6e8c053bbfdcc87b7badea4ddcf27c307' # keccak256('DisputeManager') - contractAddress: '${{DisputeManager.address}}' - - fn: 'setContractProxy' - id: '0xc713c3df6d14cdf946460395d09af88993ee2b948b1a808161494e32c5f67063' # keccak256('EpochManager') - contractAddress: '${{EpochManager.address}}' - - fn: 'setContractProxy' - id: '0x966f1e8d8d8014e05f6ec4a57138da9be1f7c5a7f802928a18072f7c53180761' # keccak256('RewardsManager') - contractAddress: '${{RewardsManager.address}}' - - fn: 'setContractProxy' - id: '0x1df41cd916959d1163dc8f0671a666ea8a3e434c13e40faef527133b5d167034' # keccak256('Staking') - contractAddress: '${{L1Staking.address}}' - - fn: 'setContractProxy' - id: '0x45fc200c7e4544e457d3c5709bfe0d520442c30bbcbdaede89e8d4a4bbc19247' # keccak256('GraphToken') - contractAddress: '${{GraphToken.address}}' - - fn: 'setContractProxy' - id: '0xd362cac9cb75c10d67bcc0b7eeb0b1ef48bb5420b556c092d4fd7f758816fcf0' # keccak256('GraphTokenGateway') - contractAddress: '${{L1GraphTokenGateway.address}}' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - - fn: 'transferOwnership' - owner: *governor - GraphProxyAdmin: - calls: - - fn: 'transferOwnership' - owner: *governor - ServiceRegistry: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - EpochManager: - proxy: true - init: - controller: '${{Controller.address}}' - lengthInBlocks: 554 # length in hours = lengthInBlocks*13/60/60 (~13 second blocks) - GraphToken: - init: - initialSupply: '10000000000000000000000000000' # in wei - calls: - - fn: 'addMinter' - minter: '${{RewardsManager.address}}' - - fn: 'addMinter' - minter: '${{L1GraphTokenGateway.address}}' - - fn: 'renounceMinter' - - fn: 'transferOwnership' - owner: *governor - Curation: - proxy: true - init: - controller: '${{Controller.address}}' - bondingCurve: '${{BancorFormula.address}}' - curationTokenMaster: '${{GraphCurationToken.address}}' - reserveRatio: 500000 # in parts per million - curationTaxPercentage: 10000 # in parts per million - minimumCurationDeposit: '1000000000000000000' # in wei - calls: - - fn: 'syncAllContracts' - DisputeManager: - proxy: true - init: - controller: '${{Controller.address}}' - arbitrator: *arbitrator - minimumDeposit: '10000000000000000000000' # in wei - fishermanRewardPercentage: 500000 # in parts per million - idxSlashingPercentage: 25000 # in parts per million - qrySlashingPercentage: 25000 # in parts per million - calls: - - fn: 'syncAllContracts' - L1GNS: - proxy: true - init: - controller: '${{Controller.address}}' - subgraphNFT: '${{SubgraphNFT.address}}' - calls: - - fn: 'approveAll' - - fn: 'syncAllContracts' - SubgraphNFT: - init: - governor: '${{Env.deployer}}' - calls: - - fn: 'setTokenDescriptor' - tokenDescriptor: '${{SubgraphNFTDescriptor.address}}' - - fn: 'setMinter' - minter: '${{L1GNS.address}}' - - fn: 'transferOwnership' - owner: *governor - L1Staking: - proxy: true - init: - controller: '${{Controller.address}}' - minimumIndexerStake: '100000000000000000000000' # in wei - thawingPeriod: 6646 # in blocks - protocolPercentage: 10000 # in parts per million - curationPercentage: 100000 # in parts per million - maxAllocationEpochs: 4 # in epochs - delegationUnbondingPeriod: 12 # in epochs - delegationRatio: 16 # delegated stake to indexer stake multiplier - rebateParameters: - alphaNumerator: 100 # alphaNumerator / alphaDenominator - alphaDenominator: 100 # alphaNumerator / alphaDenominator - lambdaNumerator: 60 # lambdaNumerator / lambdaDenominator - lambdaDenominator: 100 # lambdaNumerator / lambdaDenominator - extensionImpl: '${{StakingExtension.address}}' - calls: - - fn: 'setDelegationTaxPercentage' - delegationTaxPercentage: 5000 # parts per million - - fn: 'setSlasher' - slasher: '${{DisputeManager.address}}' - allowed: true - - fn: 'syncAllContracts' - RewardsManager: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'setIssuancePerBlock' - issuancePerBlock: '114693500000000000000' # per block increase of total supply, blocks in a year = 365*60*60*24/12 - - fn: 'setSubgraphAvailabilityOracle' - subgraphAvailabilityOracle: *availabilityOracle - - fn: 'syncAllContracts' - AllocationExchange: - init: - graphToken: '${{GraphToken.address}}' - staking: '${{L1Staking.address}}' - governor: *allocationExchangeOwner - authority: *authority - calls: - - fn: 'approveAll' - L1GraphTokenGateway: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' - - fn: 'setPauseGuardian' - pauseGuardian: *pauseGuardian - BridgeEscrow: - proxy: true - init: - controller: '${{Controller.address}}' - calls: - - fn: 'syncAllContracts' diff --git a/packages/contracts/contracts/bancor/BancorFormula.sol b/packages/contracts/contracts/bancor/BancorFormula.sol deleted file mode 100644 index 0d221be56..000000000 --- a/packages/contracts/contracts/bancor/BancorFormula.sol +++ /dev/null @@ -1,791 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.7.6; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable function-max-lines, gas-increment-by-one, gas-strict-inequalities - -import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; - -/** - * @title Bancor Formula Contract - * @author Edge & Node - * @notice Contract implementing Bancor's bonding curve formula for token conversion - */ -contract BancorFormula { - using SafeMath for uint256; - - /// @notice Version of the Bancor formula implementation - uint16 public constant version = 6; // solhint-disable-line const-name-snakecase - - /// @dev Constant representing the value 1 - uint256 private constant ONE = 1; - /// @dev Maximum ratio value (100% in parts per million) - uint32 private constant MAX_RATIO = 1000000; - /// @dev Minimum precision for calculations - uint8 private constant MIN_PRECISION = 32; - /// @dev Maximum precision for calculations - uint8 private constant MAX_PRECISION = 127; - - /** - * @dev Auto-generated via 'PrintIntScalingFactors.py' - */ - /// @dev Fixed point representation of 1 (2^127) - uint256 private constant FIXED_1 = 0x080000000000000000000000000000000; - /// @dev Fixed point representation of 2 (2^128) - uint256 private constant FIXED_2 = 0x100000000000000000000000000000000; - /// @dev Maximum number for calculations (2^129) - uint256 private constant MAX_NUM = 0x200000000000000000000000000000000; - - /** - * @dev Auto-generated via 'PrintLn2ScalingFactors.py' - */ - /// @dev Natural logarithm of 2 numerator for fixed point calculations - uint256 private constant LN2_NUMERATOR = 0x3f80fe03f80fe03f80fe03f80fe03f8; - /// @dev Natural logarithm of 2 denominator for fixed point calculations - uint256 private constant LN2_DENOMINATOR = 0x5b9de1d10bf4103d647b0955897ba80; - - /** - * @dev Auto-generated via 'PrintFunctionOptimalLog.py' and 'PrintFunctionOptimalExp.py' - */ - /// @dev Maximum value for optimal logarithm calculation - uint256 private constant OPT_LOG_MAX_VAL = 0x15bf0a8b1457695355fb8ac404e7a79e3; - /// @dev Maximum value for optimal exponentiation calculation - uint256 private constant OPT_EXP_MAX_VAL = 0x800000000000000000000000000000000; - - /** - * @dev Auto-generated via 'PrintFunctionConstructor.py' - */ - uint256[128] private maxExpArray; - - /// @notice Initialize the Bancor formula with maximum exponent array values - constructor() { - // maxExpArray[ 0] = 0x6bffffffffffffffffffffffffffffffff; - // maxExpArray[ 1] = 0x67ffffffffffffffffffffffffffffffff; - // maxExpArray[ 2] = 0x637fffffffffffffffffffffffffffffff; - // maxExpArray[ 3] = 0x5f6fffffffffffffffffffffffffffffff; - // maxExpArray[ 4] = 0x5b77ffffffffffffffffffffffffffffff; - // maxExpArray[ 5] = 0x57b3ffffffffffffffffffffffffffffff; - // maxExpArray[ 6] = 0x5419ffffffffffffffffffffffffffffff; - // maxExpArray[ 7] = 0x50a2ffffffffffffffffffffffffffffff; - // maxExpArray[ 8] = 0x4d517fffffffffffffffffffffffffffff; - // maxExpArray[ 9] = 0x4a233fffffffffffffffffffffffffffff; - // maxExpArray[ 10] = 0x47165fffffffffffffffffffffffffffff; - // maxExpArray[ 11] = 0x4429afffffffffffffffffffffffffffff; - // maxExpArray[ 12] = 0x415bc7ffffffffffffffffffffffffffff; - // maxExpArray[ 13] = 0x3eab73ffffffffffffffffffffffffffff; - // maxExpArray[ 14] = 0x3c1771ffffffffffffffffffffffffffff; - // maxExpArray[ 15] = 0x399e96ffffffffffffffffffffffffffff; - // maxExpArray[ 16] = 0x373fc47fffffffffffffffffffffffffff; - // maxExpArray[ 17] = 0x34f9e8ffffffffffffffffffffffffffff; - // maxExpArray[ 18] = 0x32cbfd5fffffffffffffffffffffffffff; - // maxExpArray[ 19] = 0x30b5057fffffffffffffffffffffffffff; - // maxExpArray[ 20] = 0x2eb40f9fffffffffffffffffffffffffff; - // maxExpArray[ 21] = 0x2cc8340fffffffffffffffffffffffffff; - // maxExpArray[ 22] = 0x2af09481ffffffffffffffffffffffffff; - // maxExpArray[ 23] = 0x292c5bddffffffffffffffffffffffffff; - // maxExpArray[ 24] = 0x277abdcdffffffffffffffffffffffffff; - // maxExpArray[ 25] = 0x25daf6657fffffffffffffffffffffffff; - // maxExpArray[ 26] = 0x244c49c65fffffffffffffffffffffffff; - // maxExpArray[ 27] = 0x22ce03cd5fffffffffffffffffffffffff; - // maxExpArray[ 28] = 0x215f77c047ffffffffffffffffffffffff; - // maxExpArray[ 29] = 0x1fffffffffffffffffffffffffffffffff; - // maxExpArray[ 30] = 0x1eaefdbdabffffffffffffffffffffffff; - // maxExpArray[ 31] = 0x1d6bd8b2ebffffffffffffffffffffffff; - maxExpArray[32] = 0x1c35fedd14ffffffffffffffffffffffff; - maxExpArray[33] = 0x1b0ce43b323fffffffffffffffffffffff; - maxExpArray[34] = 0x19f0028ec1ffffffffffffffffffffffff; - maxExpArray[35] = 0x18ded91f0e7fffffffffffffffffffffff; - maxExpArray[36] = 0x17d8ec7f0417ffffffffffffffffffffff; - maxExpArray[37] = 0x16ddc6556cdbffffffffffffffffffffff; - maxExpArray[38] = 0x15ecf52776a1ffffffffffffffffffffff; - maxExpArray[39] = 0x15060c256cb2ffffffffffffffffffffff; - maxExpArray[40] = 0x1428a2f98d72ffffffffffffffffffffff; - maxExpArray[41] = 0x13545598e5c23fffffffffffffffffffff; - maxExpArray[42] = 0x1288c4161ce1dfffffffffffffffffffff; - maxExpArray[43] = 0x11c592761c666fffffffffffffffffffff; - maxExpArray[44] = 0x110a688680a757ffffffffffffffffffff; - maxExpArray[45] = 0x1056f1b5bedf77ffffffffffffffffffff; - maxExpArray[46] = 0x0faadceceeff8bffffffffffffffffffff; - maxExpArray[47] = 0x0f05dc6b27edadffffffffffffffffffff; - maxExpArray[48] = 0x0e67a5a25da4107fffffffffffffffffff; - maxExpArray[49] = 0x0dcff115b14eedffffffffffffffffffff; - maxExpArray[50] = 0x0d3e7a392431239fffffffffffffffffff; - maxExpArray[51] = 0x0cb2ff529eb71e4fffffffffffffffffff; - maxExpArray[52] = 0x0c2d415c3db974afffffffffffffffffff; - maxExpArray[53] = 0x0bad03e7d883f69bffffffffffffffffff; - maxExpArray[54] = 0x0b320d03b2c343d5ffffffffffffffffff; - maxExpArray[55] = 0x0abc25204e02828dffffffffffffffffff; - maxExpArray[56] = 0x0a4b16f74ee4bb207fffffffffffffffff; - maxExpArray[57] = 0x09deaf736ac1f569ffffffffffffffffff; - maxExpArray[58] = 0x0976bd9952c7aa957fffffffffffffffff; - maxExpArray[59] = 0x09131271922eaa606fffffffffffffffff; - maxExpArray[60] = 0x08b380f3558668c46fffffffffffffffff; - maxExpArray[61] = 0x0857ddf0117efa215bffffffffffffffff; - maxExpArray[62] = 0x07ffffffffffffffffffffffffffffffff; - maxExpArray[63] = 0x07abbf6f6abb9d087fffffffffffffffff; - maxExpArray[64] = 0x075af62cbac95f7dfa7fffffffffffffff; - maxExpArray[65] = 0x070d7fb7452e187ac13fffffffffffffff; - maxExpArray[66] = 0x06c3390ecc8af379295fffffffffffffff; - maxExpArray[67] = 0x067c00a3b07ffc01fd6fffffffffffffff; - maxExpArray[68] = 0x0637b647c39cbb9d3d27ffffffffffffff; - maxExpArray[69] = 0x05f63b1fc104dbd39587ffffffffffffff; - maxExpArray[70] = 0x05b771955b36e12f7235ffffffffffffff; - maxExpArray[71] = 0x057b3d49dda84556d6f6ffffffffffffff; - maxExpArray[72] = 0x054183095b2c8ececf30ffffffffffffff; - maxExpArray[73] = 0x050a28be635ca2b888f77fffffffffffff; - maxExpArray[74] = 0x04d5156639708c9db33c3fffffffffffff; - maxExpArray[75] = 0x04a23105873875bd52dfdfffffffffffff; - maxExpArray[76] = 0x0471649d87199aa990756fffffffffffff; - maxExpArray[77] = 0x04429a21a029d4c1457cfbffffffffffff; - maxExpArray[78] = 0x0415bc6d6fb7dd71af2cb3ffffffffffff; - maxExpArray[79] = 0x03eab73b3bbfe282243ce1ffffffffffff; - maxExpArray[80] = 0x03c1771ac9fb6b4c18e229ffffffffffff; - maxExpArray[81] = 0x0399e96897690418f785257fffffffffff; - maxExpArray[82] = 0x0373fc456c53bb779bf0ea9fffffffffff; - maxExpArray[83] = 0x034f9e8e490c48e67e6ab8bfffffffffff; - maxExpArray[84] = 0x032cbfd4a7adc790560b3337ffffffffff; - maxExpArray[85] = 0x030b50570f6e5d2acca94613ffffffffff; - maxExpArray[86] = 0x02eb40f9f620fda6b56c2861ffffffffff; - maxExpArray[87] = 0x02cc8340ecb0d0f520a6af58ffffffffff; - maxExpArray[88] = 0x02af09481380a0a35cf1ba02ffffffffff; - maxExpArray[89] = 0x0292c5bdd3b92ec810287b1b3fffffffff; - maxExpArray[90] = 0x0277abdcdab07d5a77ac6d6b9fffffffff; - maxExpArray[91] = 0x025daf6654b1eaa55fd64df5efffffffff; - maxExpArray[92] = 0x0244c49c648baa98192dce88b7ffffffff; - maxExpArray[93] = 0x022ce03cd5619a311b2471268bffffffff; - maxExpArray[94] = 0x0215f77c045fbe885654a44a0fffffffff; - maxExpArray[95] = 0x01ffffffffffffffffffffffffffffffff; - maxExpArray[96] = 0x01eaefdbdaaee7421fc4d3ede5ffffffff; - maxExpArray[97] = 0x01d6bd8b2eb257df7e8ca57b09bfffffff; - maxExpArray[98] = 0x01c35fedd14b861eb0443f7f133fffffff; - maxExpArray[99] = 0x01b0ce43b322bcde4a56e8ada5afffffff; - maxExpArray[100] = 0x019f0028ec1fff007f5a195a39dfffffff; - maxExpArray[101] = 0x018ded91f0e72ee74f49b15ba527ffffff; - maxExpArray[102] = 0x017d8ec7f04136f4e5615fd41a63ffffff; - maxExpArray[103] = 0x016ddc6556cdb84bdc8d12d22e6fffffff; - maxExpArray[104] = 0x015ecf52776a1155b5bd8395814f7fffff; - maxExpArray[105] = 0x015060c256cb23b3b3cc3754cf40ffffff; - maxExpArray[106] = 0x01428a2f98d728ae223ddab715be3fffff; - maxExpArray[107] = 0x013545598e5c23276ccf0ede68034fffff; - maxExpArray[108] = 0x01288c4161ce1d6f54b7f61081194fffff; - maxExpArray[109] = 0x011c592761c666aa641d5a01a40f17ffff; - maxExpArray[110] = 0x0110a688680a7530515f3e6e6cfdcdffff; - maxExpArray[111] = 0x01056f1b5bedf75c6bcb2ce8aed428ffff; - maxExpArray[112] = 0x00faadceceeff8a0890f3875f008277fff; - maxExpArray[113] = 0x00f05dc6b27edad306388a600f6ba0bfff; - maxExpArray[114] = 0x00e67a5a25da41063de1495d5b18cdbfff; - maxExpArray[115] = 0x00dcff115b14eedde6fc3aa5353f2e4fff; - maxExpArray[116] = 0x00d3e7a3924312399f9aae2e0f868f8fff; - maxExpArray[117] = 0x00cb2ff529eb71e41582cccd5a1ee26fff; - maxExpArray[118] = 0x00c2d415c3db974ab32a51840c0b67edff; - maxExpArray[119] = 0x00bad03e7d883f69ad5b0a186184e06bff; - maxExpArray[120] = 0x00b320d03b2c343d4829abd6075f0cc5ff; - maxExpArray[121] = 0x00abc25204e02828d73c6e80bcdb1a95bf; - maxExpArray[122] = 0x00a4b16f74ee4bb2040a1ec6c15fbbf2df; - maxExpArray[123] = 0x009deaf736ac1f569deb1b5ae3f36c130f; - maxExpArray[124] = 0x00976bd9952c7aa957f5937d790ef65037; - maxExpArray[125] = 0x009131271922eaa6064b73a22d0bd4f2bf; - maxExpArray[126] = 0x008b380f3558668c46c91c49a2f8e967b9; - maxExpArray[127] = 0x00857ddf0117efa215952912839f6473e6; - } - - /** - * @notice Given a token supply, reserve balance, ratio and a deposit amount (in the reserve token), - * calculates the return for a given conversion (in the main token) - * - * Formula: - * Return = _supply * ((1 + _depositAmount / _reserveBalance) ^ (_reserveRatio / 1000000) - 1) - * - * @param _supply token total supply - * @param _reserveBalance total reserve balance - * @param _reserveRatio reserve ratio, represented in ppm, 1-1000000 - * @param _depositAmount deposit amount, in reserve token - * - * @return purchase return amount - */ - function calculatePurchaseReturn( - uint256 _supply, - uint256 _reserveBalance, - uint32 _reserveRatio, - uint256 _depositAmount - ) public view returns (uint256) { - // validate input - require( - _supply > 0 && _reserveBalance > 0 && _reserveRatio > 0 && _reserveRatio <= MAX_RATIO, - "invalid parameters" - ); - - // special case for 0 deposit amount - if (_depositAmount == 0) return 0; - - // special case if the ratio = 100% - if (_reserveRatio == MAX_RATIO) return _supply.mul(_depositAmount) / _reserveBalance; - - uint256 result; - uint8 precision; - uint256 baseN = _depositAmount.add(_reserveBalance); - (result, precision) = power(baseN, _reserveBalance, _reserveRatio, MAX_RATIO); - uint256 temp = _supply.mul(result) >> precision; - return temp - _supply; - } - - /** - * @notice Given a token supply, reserve balance, ratio and a sell amount (in the main token), - * calculates the return for a given conversion (in the reserve token) - * - * Formula: - * Return = _reserveBalance * (1 - (1 - _sellAmount / _supply) ^ (1000000 / _reserveRatio)) - * - * @param _supply token total supply - * @param _reserveBalance total reserve - * @param _reserveRatio constant reserve Ratio, represented in ppm, 1-1000000 - * @param _sellAmount sell amount, in the token itself - * - * @return sale return amount - */ - function calculateSaleReturn( - uint256 _supply, - uint256 _reserveBalance, - uint32 _reserveRatio, - uint256 _sellAmount - ) public view returns (uint256) { - // validate input - require( - _supply > 0 && - _reserveBalance > 0 && - _reserveRatio > 0 && - _reserveRatio <= MAX_RATIO && - _sellAmount <= _supply, - "invalid parameters" - ); - - // special case for 0 sell amount - if (_sellAmount == 0) return 0; - - // special case for selling the entire supply - if (_sellAmount == _supply) return _reserveBalance; - - // special case if the ratio = 100% - if (_reserveRatio == MAX_RATIO) return _reserveBalance.mul(_sellAmount) / _supply; - - uint256 result; - uint8 precision; - uint256 baseD = _supply - _sellAmount; - (result, precision) = power(_supply, baseD, MAX_RATIO, _reserveRatio); - uint256 temp1 = _reserveBalance.mul(result); - uint256 temp2 = _reserveBalance << precision; - return (temp1 - temp2) / result; - } - - /** - * @notice Given two reserve balances/ratios and a sell amount (in the first reserve token), - * calculates the return for a conversion from the first reserve token to the second reserve token (in the second reserve token) - * note that prior to version 4, you should use 'calculateCrossConnectorReturn' instead - * - * Formula: - * Return = _toReserveBalance * (1 - (_fromReserveBalance / (_fromReserveBalance + _amount)) ^ (_fromReserveRatio / _toReserveRatio)) - * - * @param _fromReserveBalance input reserve balance - * @param _fromReserveRatio input reserve ratio, represented in ppm, 1-1000000 - * @param _toReserveBalance output reserve balance - * @param _toReserveRatio output reserve ratio, represented in ppm, 1-1000000 - * @param _amount input reserve amount - * - * @return second reserve amount - */ - function calculateCrossReserveReturn( - uint256 _fromReserveBalance, - uint32 _fromReserveRatio, - uint256 _toReserveBalance, - uint32 _toReserveRatio, - uint256 _amount - ) public view returns (uint256) { - // validate input - require( - _fromReserveBalance > 0 && - _fromReserveRatio > 0 && - _fromReserveRatio <= MAX_RATIO && - _toReserveBalance > 0 && - _toReserveRatio > 0 && - _toReserveRatio <= MAX_RATIO - ); - - // special case for equal ratios - if (_fromReserveRatio == _toReserveRatio) - return _toReserveBalance.mul(_amount) / _fromReserveBalance.add(_amount); - - uint256 result; - uint8 precision; - uint256 baseN = _fromReserveBalance.add(_amount); - (result, precision) = power(baseN, _fromReserveBalance, _fromReserveRatio, _toReserveRatio); - uint256 temp1 = _toReserveBalance.mul(result); - uint256 temp2 = _toReserveBalance << precision; - return (temp1 - temp2) / result; - } - - /** - * @notice Given a smart token supply, reserve balance, total ratio and an amount of requested smart tokens, - * calculates the amount of reserve tokens required for purchasing the given amount of smart tokens - * - * Formula: - * Return = _reserveBalance * (((_supply + _amount) / _supply) ^ (MAX_RATIO / _totalRatio) - 1) - * - * @param _supply smart token supply - * @param _reserveBalance reserve token balance - * @param _totalRatio total ratio, represented in ppm, 2-2000000 - * @param _amount requested amount of smart tokens - * - * @return amount of reserve tokens - */ - function calculateFundCost( - uint256 _supply, - uint256 _reserveBalance, - uint32 _totalRatio, - uint256 _amount - ) public view returns (uint256) { - // validate input - require(_supply > 0 && _reserveBalance > 0 && _totalRatio > 1 && _totalRatio <= MAX_RATIO * 2); - - // special case for 0 amount - if (_amount == 0) return 0; - - // special case if the total ratio = 100% - if (_totalRatio == MAX_RATIO) return (_amount.mul(_reserveBalance) - 1) / _supply + 1; - - uint256 result; - uint8 precision; - uint256 baseN = _supply.add(_amount); - (result, precision) = power(baseN, _supply, MAX_RATIO, _totalRatio); - uint256 temp = ((_reserveBalance.mul(result) - 1) >> precision) + 1; - return temp - _reserveBalance; - } - - /** - * @notice Given a smart token supply, reserve balance, total ratio and an amount of smart tokens to liquidate, - * calculates the amount of reserve tokens received for selling the given amount of smart tokens - * - * Formula: - * Return = _reserveBalance * (1 - ((_supply - _amount) / _supply) ^ (MAX_RATIO / _totalRatio)) - * - * @param _supply smart token supply - * @param _reserveBalance reserve token balance - * @param _totalRatio total ratio, represented in ppm, 2-2000000 - * @param _amount amount of smart tokens to liquidate - * - * @return amount of reserve tokens - */ - function calculateLiquidateReturn( - uint256 _supply, - uint256 _reserveBalance, - uint32 _totalRatio, - uint256 _amount - ) public view returns (uint256) { - // validate input - require( - _supply > 0 && _reserveBalance > 0 && _totalRatio > 1 && _totalRatio <= MAX_RATIO * 2 && _amount <= _supply - ); - - // special case for 0 amount - if (_amount == 0) return 0; - - // special case for liquidating the entire supply - if (_amount == _supply) return _reserveBalance; - - // special case if the total ratio = 100% - if (_totalRatio == MAX_RATIO) return _amount.mul(_reserveBalance) / _supply; - - uint256 result; - uint8 precision; - uint256 baseD = _supply - _amount; - (result, precision) = power(_supply, baseD, MAX_RATIO, _totalRatio); - uint256 temp1 = _reserveBalance.mul(result); - uint256 temp2 = _reserveBalance << precision; - return (temp1 - temp2) / result; - } - - /** - * @notice General Description: - * Determine a value of precision. - * Calculate an integer approximation of (_baseN / _baseD) ^ (_expN / _expD) * 2 ^ precision. - * Return the result along with the precision used. - * - * Detailed Description: - * Instead of calculating "base ^ exp", we calculate "e ^ (log(base) * exp)". - * The value of "log(base)" is represented with an integer slightly smaller than "log(base) * 2 ^ precision". - * The larger "precision" is, the more accurately this value represents the real value. - * However, the larger "precision" is, the more bits are required in order to store this value. - * And the exponentiation function, which takes "x" and calculates "e ^ x", is limited to a maximum exponent (maximum value of "x"). - * This maximum exponent depends on the "precision" used, and it is given by "maxExpArray[precision] >> (MAX_PRECISION - precision)". - * Hence we need to determine the highest precision which can be used for the given input, before calling the exponentiation function. - * This allows us to compute "base ^ exp" with maximum accuracy and without exceeding 256 bits in any of the intermediate computations. - * This functions assumes that "_expN < 2 ^ 256 / log(MAX_NUM - 1)", otherwise the multiplication should be replaced with a "safeMul". - * Since we rely on unsigned-integer arithmetic and "base < 1" ==> "log(base) < 0", this function does not support "_baseN < _baseD". - * @param _baseN Base numerator - * @param _baseD Base denominator - * @param _expN Exponent numerator - * @param _expD Exponent denominator - * @return result The computed power result - * @return precision The precision used in the calculation - */ - function power(uint256 _baseN, uint256 _baseD, uint32 _expN, uint32 _expD) internal view returns (uint256, uint8) { - require(_baseN < MAX_NUM); - - uint256 baseLog; - uint256 base = (_baseN * FIXED_1) / _baseD; - if (base < OPT_LOG_MAX_VAL) { - baseLog = optimalLog(base); - } else { - baseLog = generalLog(base); - } - - uint256 baseLogTimesExp = (baseLog * _expN) / _expD; - if (baseLogTimesExp < OPT_EXP_MAX_VAL) { - return (optimalExp(baseLogTimesExp), MAX_PRECISION); - } else { - uint8 precision = findPositionInMaxExpArray(baseLogTimesExp); - return (generalExp(baseLogTimesExp >> (MAX_PRECISION - precision), precision), precision); - } - } - - /** - * @notice Computes log(x / FIXED_1) * FIXED_1. - * This functions assumes that "x >= FIXED_1", because the output would be negative otherwise. - * @param x The input value (must be >= FIXED_1) - * @return The computed logarithm - */ - function generalLog(uint256 x) internal pure returns (uint256) { - uint256 res = 0; - - // If x >= 2, then we compute the integer part of log2(x), which is larger than 0. - if (x >= FIXED_2) { - uint8 count = floorLog2(x / FIXED_1); - x >>= count; // now x < 2 - res = count * FIXED_1; - } - - // If x > 1, then we compute the fraction part of log2(x), which is larger than 0. - if (x > FIXED_1) { - for (uint8 i = MAX_PRECISION; i > 0; --i) { - x = (x * x) / FIXED_1; // now 1 < x < 4 - if (x >= FIXED_2) { - x >>= 1; // now 1 < x < 2 - res += ONE << (i - 1); - } - } - } - - return (res * LN2_NUMERATOR) / LN2_DENOMINATOR; - } - - /** - * @notice Computes the largest integer smaller than or equal to the binary logarithm of the input. - * @param _n The input value - * @return The floor of the binary logarithm - */ - function floorLog2(uint256 _n) internal pure returns (uint8) { - uint8 res = 0; - - if (_n < 256) { - // At most 8 iterations - while (_n > 1) { - _n >>= 1; - res += 1; - } - } else { - // Exactly 8 iterations - for (uint8 s = 128; s > 0; s >>= 1) { - if (_n >= (ONE << s)) { - _n >>= s; - res |= s; - } - } - } - - return res; - } - - /** - * @notice The global "maxExpArray" is sorted in descending order, and therefore the following statements are equivalent: - * - This function finds the position of [the smallest value in "maxExpArray" larger than or equal to "x"] - * - This function finds the highest position of [a value in "maxExpArray" larger than or equal to "x"] - * @param _x The value to find position for - * @return The position in the maxExpArray - */ - function findPositionInMaxExpArray(uint256 _x) internal view returns (uint8) { - uint8 lo = MIN_PRECISION; - uint8 hi = MAX_PRECISION; - - while (lo + 1 < hi) { - uint8 mid = (lo + hi) / 2; - if (maxExpArray[mid] >= _x) lo = mid; - else hi = mid; - } - - if (maxExpArray[hi] >= _x) return hi; - if (maxExpArray[lo] >= _x) return lo; - - require(false); - return 0; - } - - /** - * @notice This function can be auto-generated by the script 'PrintFunctionGeneralExp.py'. - * it approximates "e ^ x" via maclaurin summation: "(x^0)/0! + (x^1)/1! + ... + (x^n)/n!". - * it returns "e ^ (x / 2 ^ precision) * 2 ^ precision", that is, the result is upshifted for accuracy. - * the global "maxExpArray" maps each "precision" to "((maximumExponent + 1) << (MAX_PRECISION - precision)) - 1". - * the maximum permitted value for "x" is therefore given by "maxExpArray[precision] >> (MAX_PRECISION - precision)". - * @param _x The exponent value - * @param _precision The precision to use - * @return The computed exponential result - */ - function generalExp(uint256 _x, uint8 _precision) internal pure returns (uint256) { - uint256 xi = _x; - uint256 res = 0; - - xi = (xi * _x) >> _precision; - res += xi * 0x3442c4e6074a82f1797f72ac0000000; // add x^02 * (33! / 02!) - xi = (xi * _x) >> _precision; - res += xi * 0x116b96f757c380fb287fd0e40000000; // add x^03 * (33! / 03!) - xi = (xi * _x) >> _precision; - res += xi * 0x045ae5bdd5f0e03eca1ff4390000000; // add x^04 * (33! / 04!) - xi = (xi * _x) >> _precision; - res += xi * 0x00defabf91302cd95b9ffda50000000; // add x^05 * (33! / 05!) - xi = (xi * _x) >> _precision; - res += xi * 0x002529ca9832b22439efff9b8000000; // add x^06 * (33! / 06!) - xi = (xi * _x) >> _precision; - res += xi * 0x00054f1cf12bd04e516b6da88000000; // add x^07 * (33! / 07!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000a9e39e257a09ca2d6db51000000; // add x^08 * (33! / 08!) - xi = (xi * _x) >> _precision; - res += xi * 0x000012e066e7b839fa050c309000000; // add x^09 * (33! / 09!) - xi = (xi * _x) >> _precision; - res += xi * 0x000001e33d7d926c329a1ad1a800000; // add x^10 * (33! / 10!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000002bee513bdb4a6b19b5f800000; // add x^11 * (33! / 11!) - xi = (xi * _x) >> _precision; - res += xi * 0x00000003a9316fa79b88eccf2a00000; // add x^12 * (33! / 12!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000000048177ebe1fa812375200000; // add x^13 * (33! / 13!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000000005263fe90242dcbacf00000; // add x^14 * (33! / 14!) - xi = (xi * _x) >> _precision; - res += xi * 0x000000000057e22099c030d94100000; // add x^15 * (33! / 15!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000000000057e22099c030d9410000; // add x^16 * (33! / 16!) - xi = (xi * _x) >> _precision; - res += xi * 0x00000000000052b6b54569976310000; // add x^17 * (33! / 17!) - xi = (xi * _x) >> _precision; - res += xi * 0x00000000000004985f67696bf748000; // add x^18 * (33! / 18!) - xi = (xi * _x) >> _precision; - res += xi * 0x000000000000003dea12ea99e498000; // add x^19 * (33! / 19!) - xi = (xi * _x) >> _precision; - res += xi * 0x00000000000000031880f2214b6e000; // add x^20 * (33! / 20!) - xi = (xi * _x) >> _precision; - res += xi * 0x000000000000000025bcff56eb36000; // add x^21 * (33! / 21!) - xi = (xi * _x) >> _precision; - res += xi * 0x000000000000000001b722e10ab1000; // add x^22 * (33! / 22!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000000000000000001317c70077000; // add x^23 * (33! / 23!) - xi = (xi * _x) >> _precision; - res += xi * 0x00000000000000000000cba84aafa00; // add x^24 * (33! / 24!) - xi = (xi * _x) >> _precision; - res += xi * 0x00000000000000000000082573a0a00; // add x^25 * (33! / 25!) - xi = (xi * _x) >> _precision; - res += xi * 0x00000000000000000000005035ad900; // add x^26 * (33! / 26!) - xi = (xi * _x) >> _precision; - res += xi * 0x000000000000000000000002f881b00; // add x^27 * (33! / 27!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000000000000000000000001b29340; // add x^28 * (33! / 28!) - xi = (xi * _x) >> _precision; - res += xi * 0x00000000000000000000000000efc40; // add x^29 * (33! / 29!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000000000000000000000000007fe0; // add x^30 * (33! / 30!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000000000000000000000000000420; // add x^31 * (33! / 31!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000000000000000000000000000021; // add x^32 * (33! / 32!) - xi = (xi * _x) >> _precision; - res += xi * 0x0000000000000000000000000000001; // add x^33 * (33! / 33!) - - return res / 0x688589cc0e9505e2f2fee5580000000 + _x + (ONE << _precision); // divide by 33! and then add x^1 / 1! + x^0 / 0! - } - - /** - * @notice Computes log(x / FIXED_1) * FIXED_1 - * Input range: FIXED_1 <= x <= LOG_EXP_MAX_VAL - 1 - * Auto-generated via 'PrintFunctionOptimalLog.py' - * Detailed description: - * - Rewrite the input as a product of natural exponents and a single residual r, such that 1 < r < 2 - * - The natural logarithm of each (pre-calculated) exponent is the degree of the exponent - * - The natural logarithm of r is calculated via Taylor series for log(1 + x), where x = r - 1 - * - The natural logarithm of the input is calculated by summing up the intermediate results above - * - For example: log(250) = log(e^4 * e^1 * e^0.5 * 1.021692859) = 4 + 1 + 0.5 + log(1 + 0.021692859) - * @param x The input value - * @return The computed logarithm - */ - function optimalLog(uint256 x) internal pure returns (uint256) { - uint256 res = 0; - - uint256 y; - uint256 z; - uint256 w; - - if (x >= 0xd3094c70f034de4b96ff7d5b6f99fcd8) { - res += 0x40000000000000000000000000000000; - x = (x * FIXED_1) / 0xd3094c70f034de4b96ff7d5b6f99fcd8; - } // add 1 / 2^1 - if (x >= 0xa45af1e1f40c333b3de1db4dd55f29a7) { - res += 0x20000000000000000000000000000000; - x = (x * FIXED_1) / 0xa45af1e1f40c333b3de1db4dd55f29a7; - } // add 1 / 2^2 - if (x >= 0x910b022db7ae67ce76b441c27035c6a1) { - res += 0x10000000000000000000000000000000; - x = (x * FIXED_1) / 0x910b022db7ae67ce76b441c27035c6a1; - } // add 1 / 2^3 - if (x >= 0x88415abbe9a76bead8d00cf112e4d4a8) { - res += 0x08000000000000000000000000000000; - x = (x * FIXED_1) / 0x88415abbe9a76bead8d00cf112e4d4a8; - } // add 1 / 2^4 - if (x >= 0x84102b00893f64c705e841d5d4064bd3) { - res += 0x04000000000000000000000000000000; - x = (x * FIXED_1) / 0x84102b00893f64c705e841d5d4064bd3; - } // add 1 / 2^5 - if (x >= 0x8204055aaef1c8bd5c3259f4822735a2) { - res += 0x02000000000000000000000000000000; - x = (x * FIXED_1) / 0x8204055aaef1c8bd5c3259f4822735a2; - } // add 1 / 2^6 - if (x >= 0x810100ab00222d861931c15e39b44e99) { - res += 0x01000000000000000000000000000000; - x = (x * FIXED_1) / 0x810100ab00222d861931c15e39b44e99; - } // add 1 / 2^7 - if (x >= 0x808040155aabbbe9451521693554f733) { - res += 0x00800000000000000000000000000000; - x = (x * FIXED_1) / 0x808040155aabbbe9451521693554f733; - } // add 1 / 2^8 - - z = y = x - FIXED_1; - w = (y * y) / FIXED_1; - res += (z * (0x100000000000000000000000000000000 - y)) / 0x100000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^01 / 01 - y^02 / 02 - res += (z * (0x0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - y)) / 0x200000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^03 / 03 - y^04 / 04 - res += (z * (0x099999999999999999999999999999999 - y)) / 0x300000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^05 / 05 - y^06 / 06 - res += (z * (0x092492492492492492492492492492492 - y)) / 0x400000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^07 / 07 - y^08 / 08 - res += (z * (0x08e38e38e38e38e38e38e38e38e38e38e - y)) / 0x500000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^09 / 09 - y^10 / 10 - res += (z * (0x08ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b - y)) / 0x600000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^11 / 11 - y^12 / 12 - res += (z * (0x089d89d89d89d89d89d89d89d89d89d89 - y)) / 0x700000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^13 / 13 - y^14 / 14 - res += (z * (0x088888888888888888888888888888888 - y)) / 0x800000000000000000000000000000000; // add y^15 / 15 - y^16 / 16 - - return res; - } - - /** - * @notice Computes e ^ (x / FIXED_1) * FIXED_1 - * input range: 0 <= x <= OPT_EXP_MAX_VAL - 1 - * auto-generated via 'PrintFunctionOptimalExp.py' - * Detailed description: - * - Rewrite the input as a sum of binary exponents and a single residual r, as small as possible - * - The exponentiation of each binary exponent is given (pre-calculated) - * - The exponentiation of r is calculated via Taylor series for e^x, where x = r - * - The exponentiation of the input is calculated by multiplying the intermediate results above - * - For example: e^5.521692859 = e^(4 + 1 + 0.5 + 0.021692859) = e^4 * e^1 * e^0.5 * e^0.021692859 - * @param x The input value - * @return The computed exponential result - */ - function optimalExp(uint256 x) internal pure returns (uint256) { - uint256 res = 0; - - uint256 y; - uint256 z; - - z = y = x % 0x10000000000000000000000000000000; // get the input modulo 2^(-3) - z = (z * y) / FIXED_1; - res += z * 0x10e1b3be415a0000; // add y^02 * (20! / 02!) - z = (z * y) / FIXED_1; - res += z * 0x05a0913f6b1e0000; // add y^03 * (20! / 03!) - z = (z * y) / FIXED_1; - res += z * 0x0168244fdac78000; // add y^04 * (20! / 04!) - z = (z * y) / FIXED_1; - res += z * 0x004807432bc18000; // add y^05 * (20! / 05!) - z = (z * y) / FIXED_1; - res += z * 0x000c0135dca04000; // add y^06 * (20! / 06!) - z = (z * y) / FIXED_1; - res += z * 0x0001b707b1cdc000; // add y^07 * (20! / 07!) - z = (z * y) / FIXED_1; - res += z * 0x000036e0f639b800; // add y^08 * (20! / 08!) - z = (z * y) / FIXED_1; - res += z * 0x00000618fee9f800; // add y^09 * (20! / 09!) - z = (z * y) / FIXED_1; - res += z * 0x0000009c197dcc00; // add y^10 * (20! / 10!) - z = (z * y) / FIXED_1; - res += z * 0x0000000e30dce400; // add y^11 * (20! / 11!) - z = (z * y) / FIXED_1; - res += z * 0x000000012ebd1300; // add y^12 * (20! / 12!) - z = (z * y) / FIXED_1; - res += z * 0x0000000017499f00; // add y^13 * (20! / 13!) - z = (z * y) / FIXED_1; - res += z * 0x0000000001a9d480; // add y^14 * (20! / 14!) - z = (z * y) / FIXED_1; - res += z * 0x00000000001c6380; // add y^15 * (20! / 15!) - z = (z * y) / FIXED_1; - res += z * 0x000000000001c638; // add y^16 * (20! / 16!) - z = (z * y) / FIXED_1; - res += z * 0x0000000000001ab8; // add y^17 * (20! / 17!) - z = (z * y) / FIXED_1; - res += z * 0x000000000000017c; // add y^18 * (20! / 18!) - z = (z * y) / FIXED_1; - res += z * 0x0000000000000014; // add y^19 * (20! / 19!) - z = (z * y) / FIXED_1; - res += z * 0x0000000000000001; // add y^20 * (20! / 20!) - res = res / 0x21c3677c82b40000 + y + FIXED_1; // divide by 20! and then add y^1 / 1! + y^0 / 0! - - if ((x & 0x010000000000000000000000000000000) != 0) - res = (res * 0x1c3d6a24ed82218787d624d3e5eba95f9) / 0x18ebef9eac820ae8682b9793ac6d1e776; // multiply by e^2^(-3) - if ((x & 0x020000000000000000000000000000000) != 0) - res = (res * 0x18ebef9eac820ae8682b9793ac6d1e778) / 0x1368b2fc6f9609fe7aceb46aa619baed4; // multiply by e^2^(-2) - if ((x & 0x040000000000000000000000000000000) != 0) - res = (res * 0x1368b2fc6f9609fe7aceb46aa619baed5) / 0x0bc5ab1b16779be3575bd8f0520a9f21f; // multiply by e^2^(-1) - if ((x & 0x080000000000000000000000000000000) != 0) - res = (res * 0x0bc5ab1b16779be3575bd8f0520a9f21e) / 0x0454aaa8efe072e7f6ddbab84b40a55c9; // multiply by e^2^(+0) - if ((x & 0x100000000000000000000000000000000) != 0) - res = (res * 0x0454aaa8efe072e7f6ddbab84b40a55c5) / 0x00960aadc109e7a3bf4578099615711ea; // multiply by e^2^(+1) - if ((x & 0x200000000000000000000000000000000) != 0) - res = (res * 0x00960aadc109e7a3bf4578099615711d7) / 0x0002bf84208204f5977f9a8cf01fdce3d; // multiply by e^2^(+2) - if ((x & 0x400000000000000000000000000000000) != 0) - res = (res * 0x0002bf84208204f5977f9a8cf01fdc307) / 0x0000003c6ab775dd0b95b4cbee7e65d11; // multiply by e^2^(+3) - - return res; - } - - /** - * @notice Deprecated function for backward compatibility - * @param _fromConnectorBalance input connector balance - * @param _fromConnectorWeight input connector weight - * @param _toConnectorBalance output connector balance - * @param _toConnectorWeight output connector weight - * @param _amount input connector amount - * @return output connector amount - */ - function calculateCrossConnectorReturn( - uint256 _fromConnectorBalance, - uint32 _fromConnectorWeight, - uint256 _toConnectorBalance, - uint32 _toConnectorWeight, - uint256 _amount - ) public view returns (uint256) { - return - calculateCrossReserveReturn( - _fromConnectorBalance, - _fromConnectorWeight, - _toConnectorBalance, - _toConnectorWeight, - _amount - ); - } -} diff --git a/packages/contracts/contracts/curation/Curation.sol b/packages/contracts/contracts/curation/Curation.sol deleted file mode 100644 index e7aac2cc2..000000000 --- a/packages/contracts/contracts/curation/Curation.sol +++ /dev/null @@ -1,438 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable gas-indexed-events, gas-small-strings, gas-strict-inequalities - -import { AddressUpgradeable } from "@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol"; -import { SafeMathUpgradeable } from "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; -import { ClonesUpgradeable } from "@openzeppelin/contracts-upgradeable/proxy/ClonesUpgradeable.sol"; - -import { BancorFormula } from "../bancor/BancorFormula.sol"; -import { GraphUpgradeable } from "../upgrades/GraphUpgradeable.sol"; -import { TokenUtils } from "../utils/TokenUtils.sol"; -import { IRewardsManager } from "@graphprotocol/interfaces/contracts/contracts/rewards/IRewardsManager.sol"; -import { Managed } from "../governance/Managed.sol"; -import { IGraphToken } from "@graphprotocol/interfaces/contracts/contracts/token/IGraphToken.sol"; -import { CurationV2Storage } from "./CurationStorage.sol"; -import { IGraphCurationToken } from "@graphprotocol/interfaces/contracts/contracts/curation/IGraphCurationToken.sol"; - -/** - * @title Curation contract - * @author Edge & Node - * @notice Allows curators to signal on subgraph deployments that might be relevant to indexers by - * staking Graph Tokens (GRT). Additionally, curators earn fees from the Query Market related to the - * subgraph deployment they curate. - * A curators deposit goes to a curation pool along with the deposits of other curators, - * only one such pool exists for each subgraph deployment. - * The contract mints Graph Curation Shares (GCS) according to a bonding curve for each individual - * curation pool where GRT is deposited. - * Holders can burn GCS using this contract to get GRT tokens back according to the - * bonding curve. - */ -contract Curation is CurationV2Storage, GraphUpgradeable { - using SafeMathUpgradeable for uint256; - - /// @dev 100% in parts per million - uint32 private constant MAX_PPM = 1000000; - - /// @dev Amount of signal you get with your minimum token deposit - uint256 private constant SIGNAL_PER_MINIMUM_DEPOSIT = 1e18; // 1 signal as 18 decimal number - - // -- Events -- - - /** - * @notice Emitted when `curator` deposited `tokens` on `subgraphDeploymentID` as curation signal. - * The `curator` receives `signal` amount according to the curation pool bonding curve. - * An amount of `curationTax` will be collected and burned. - * @param curator Address of the curator - * @param subgraphDeploymentID Subgraph deployment being signaled on - * @param tokens Amount of tokens deposited - * @param signal Amount of signal minted - * @param curationTax Amount of tokens burned as curation tax - */ - event Signalled( - address indexed curator, - bytes32 indexed subgraphDeploymentID, - uint256 tokens, - uint256 signal, - uint256 curationTax - ); - - /** - * @notice Emitted when `curator` burned `signal` for a `subgraphDeploymentID`. - * The curator will receive `tokens` according to the value of the bonding curve. - * @param curator Address of the curator - * @param subgraphDeploymentID Subgraph deployment being signaled on - * @param tokens Amount of tokens received - * @param signal Amount of signal burned - */ - event Burned(address indexed curator, bytes32 indexed subgraphDeploymentID, uint256 tokens, uint256 signal); - - /** - * @notice Emitted when `tokens` amount were collected for `subgraphDeploymentID` as part of fees - * distributed by an indexer from query fees received from state channels. - * @param subgraphDeploymentID Subgraph deployment that collected fees - * @param tokens Amount of tokens collected as fees - */ - event Collected(bytes32 indexed subgraphDeploymentID, uint256 tokens); - - /** - * @notice Initialize this contract. - * @param _controller Address of the controller contract that manages this contract - * @param _bondingCurve Address of the bonding curve contract (e.g. a BancorFormula) - * @param _curationTokenMaster Address of the master copy to use for curation tokens - * @param _defaultReserveRatio Default reserve ratio for a curation pool in PPM - * @param _curationTaxPercentage Percentage of curation tax to charge when depositing GRT tokens - * @param _minimumCurationDeposit Minimum amount of tokens that can be deposited on a new subgraph deployment - */ - function initialize( - address _controller, - address _bondingCurve, - address _curationTokenMaster, - uint32 _defaultReserveRatio, - uint32 _curationTaxPercentage, - uint256 _minimumCurationDeposit - ) external onlyImpl initializer { - Managed._initialize(_controller); - - require(_bondingCurve != address(0), "Bonding curve must be set"); - bondingCurve = _bondingCurve; - - // Settings - _setDefaultReserveRatio(_defaultReserveRatio); - _setCurationTaxPercentage(_curationTaxPercentage); - _setMinimumCurationDeposit(_minimumCurationDeposit); - _setCurationTokenMaster(_curationTokenMaster); - } - - /** - * @notice Set the default reserve ratio percentage for a curation pool. - * @param _defaultReserveRatio Reserve ratio (in PPM) - */ - function setDefaultReserveRatio(uint32 _defaultReserveRatio) external override onlyGovernor { - _setDefaultReserveRatio(_defaultReserveRatio); - } - - /** - * @notice Set the minimum deposit amount for curators. - * @param _minimumCurationDeposit Minimum amount of tokens required deposit - */ - function setMinimumCurationDeposit(uint256 _minimumCurationDeposit) external override onlyGovernor { - _setMinimumCurationDeposit(_minimumCurationDeposit); - } - - /** - * @notice Set the curation tax percentage to charge when a curator deposits GRT tokens. - * @param _percentage Curation tax percentage charged when depositing GRT tokens - */ - function setCurationTaxPercentage(uint32 _percentage) external override onlyGovernor { - _setCurationTaxPercentage(_percentage); - } - - /** - * @notice Set the master copy to use as clones for the curation token. - * @param _curationTokenMaster Address of implementation contract to use for curation tokens - */ - function setCurationTokenMaster(address _curationTokenMaster) external override onlyGovernor { - _setCurationTokenMaster(_curationTokenMaster); - } - - /** - * @notice Assign Graph Tokens collected as curation fees to the curation pool reserve. - * @dev This function can only be called by the Staking contract and will do the bookkeeping of - * transferred tokens into this contract. - * @param _subgraphDeploymentID SubgraphDeployment where funds should be allocated as reserves - * @param _tokens Amount of Graph Tokens to add to reserves - */ - function collect(bytes32 _subgraphDeploymentID, uint256 _tokens) external override { - // Only Staking contract is authorized as caller - require(msg.sender == address(staking()), "Caller must be the staking contract"); - - // Must be curated to accept tokens - require(isCurated(_subgraphDeploymentID), "Subgraph deployment must be curated to collect fees"); - - // Collect new funds into reserve - CurationPool storage curationPool = pools[_subgraphDeploymentID]; - curationPool.tokens = curationPool.tokens.add(_tokens); - - emit Collected(_subgraphDeploymentID, _tokens); - } - - /** - * @notice Deposit Graph Tokens in exchange for signal of a SubgraphDeployment curation pool. - * @param _subgraphDeploymentID Subgraph deployment pool from where to mint signal - * @param _tokensIn Amount of Graph Tokens to deposit - * @param _signalOutMin Expected minimum amount of signal to receive - * @return Amount of signal minted - * @return Amount of curation tax burned - */ - function mint( - bytes32 _subgraphDeploymentID, - uint256 _tokensIn, - uint256 _signalOutMin - ) external override notPartialPaused returns (uint256, uint256) { - // Need to deposit some funds - require(_tokensIn != 0, "Cannot deposit zero tokens"); - - // Exchange GRT tokens for GCS of the subgraph pool - (uint256 signalOut, uint256 curationTax) = tokensToSignal(_subgraphDeploymentID, _tokensIn); - - // Slippage protection - require(signalOut >= _signalOutMin, "Slippage protection"); - - address curator = msg.sender; - CurationPool storage curationPool = pools[_subgraphDeploymentID]; - - // If it hasn't been curated before then initialize the curve - if (!isCurated(_subgraphDeploymentID)) { - curationPool.reserveRatio = defaultReserveRatio; - - // If no signal token for the pool - create one - if (address(curationPool.gcs) == address(0)) { - // Use a minimal proxy to reduce gas cost - IGraphCurationToken gcs = IGraphCurationToken(ClonesUpgradeable.clone(curationTokenMaster)); - gcs.initialize(address(this)); - curationPool.gcs = gcs; - } - } - - // Trigger update rewards calculation snapshot - _updateRewards(_subgraphDeploymentID); - - // Transfer tokens from the curator to this contract - // Burn the curation tax - // NOTE: This needs to happen after _updateRewards snapshot as that function - // is using balanceOf(curation) - IGraphToken _graphToken = graphToken(); - TokenUtils.pullTokens(_graphToken, curator, _tokensIn); - TokenUtils.burnTokens(_graphToken, curationTax); - - // Update curation pool - curationPool.tokens = curationPool.tokens.add(_tokensIn.sub(curationTax)); - curationPool.gcs.mint(curator, signalOut); - - emit Signalled(curator, _subgraphDeploymentID, _tokensIn, signalOut, curationTax); - - return (signalOut, curationTax); - } - - /** - * @notice Burn _signal from the SubgraphDeployment curation pool - * @param _subgraphDeploymentID SubgraphDeployment the curator is returning signal - * @param _signalIn Amount of signal to return - * @param _tokensOutMin Expected minimum amount of tokens to receive - * @return Tokens returned - */ - function burn( - bytes32 _subgraphDeploymentID, - uint256 _signalIn, - uint256 _tokensOutMin - ) external override notPartialPaused returns (uint256) { - address curator = msg.sender; - - // Validations - require(_signalIn != 0, "Cannot burn zero signal"); - require(getCuratorSignal(curator, _subgraphDeploymentID) >= _signalIn, "Cannot burn more signal than you own"); - - // Get the amount of tokens to refund based on returned signal - uint256 tokensOut = signalToTokens(_subgraphDeploymentID, _signalIn); - - // Slippage protection - require(tokensOut >= _tokensOutMin, "Slippage protection"); - - // Trigger update rewards calculation - _updateRewards(_subgraphDeploymentID); - - // Update curation pool - CurationPool storage curationPool = pools[_subgraphDeploymentID]; - curationPool.tokens = curationPool.tokens.sub(tokensOut); - curationPool.gcs.burnFrom(curator, _signalIn); - - // If all signal burnt delete the curation pool except for the - // curation token contract to avoid recreating it on a new mint - if (getCurationPoolSignal(_subgraphDeploymentID) == 0) { - curationPool.tokens = 0; - curationPool.reserveRatio = 0; - } - - // Return the tokens to the curator - TokenUtils.pushTokens(graphToken(), curator, tokensOut); - - emit Burned(curator, _subgraphDeploymentID, tokensOut, _signalIn); - - return tokensOut; - } - - /** - * @notice Get the amount of token reserves in a curation pool. - * @param _subgraphDeploymentID Subgraph deployment curation pool - * @return Amount of token reserves in the curation pool - */ - function getCurationPoolTokens(bytes32 _subgraphDeploymentID) external view override returns (uint256) { - return pools[_subgraphDeploymentID].tokens; - } - - /** - * @notice Check if any GRT tokens are deposited for a SubgraphDeployment. - * @param _subgraphDeploymentID SubgraphDeployment to check if curated - * @return True if curated, false otherwise - */ - function isCurated(bytes32 _subgraphDeploymentID) public view override returns (bool) { - return pools[_subgraphDeploymentID].tokens != 0; - } - - /** - * @notice Get the amount of signal a curator has in a curation pool. - * @param _curator Curator owning the signal tokens - * @param _subgraphDeploymentID Subgraph deployment curation pool - * @return Amount of signal owned by a curator for the subgraph deployment - */ - function getCuratorSignal(address _curator, bytes32 _subgraphDeploymentID) public view override returns (uint256) { - IGraphCurationToken gcs = pools[_subgraphDeploymentID].gcs; - return (address(gcs) == address(0)) ? 0 : gcs.balanceOf(_curator); - } - - /** - * @notice Get the amount of signal in a curation pool. - * @param _subgraphDeploymentID Subgraph deployment curation pool - * @return Amount of signal minted for the subgraph deployment - */ - function getCurationPoolSignal(bytes32 _subgraphDeploymentID) public view override returns (uint256) { - IGraphCurationToken gcs = pools[_subgraphDeploymentID].gcs; - return (address(gcs) == address(0)) ? 0 : gcs.totalSupply(); - } - - /** - * @notice Calculate amount of signal that can be bought with tokens in a curation pool. - * This function considers and excludes the deposit tax. - * @param _subgraphDeploymentID Subgraph deployment to mint signal - * @param _tokensIn Amount of tokens used to mint signal - * @return Amount of signal that can be bought - * @return Amount of tokens that will be burned as curation tax - */ - function tokensToSignal( - bytes32 _subgraphDeploymentID, - uint256 _tokensIn - ) public view override returns (uint256, uint256) { - // NOTE: We're aware that this function rounds down and tax can be 0 for small amounts - // of tokens but since minimumCurationDeposit is 1 GRT tax will always be greater than 0. - uint256 curationTax = _tokensIn.mul(uint256(curationTaxPercentage)).div(MAX_PPM); - uint256 signalOut = _tokensToSignal(_subgraphDeploymentID, _tokensIn.sub(curationTax)); - return (signalOut, curationTax); - } - - /** - * @notice Calculate amount of signal that can be bought with tokens in a curation pool. - * @param _subgraphDeploymentID Subgraph deployment to mint signal - * @param _tokensIn Amount of tokens used to mint signal - * @return Amount of signal that can be bought with tokens - */ - function _tokensToSignal(bytes32 _subgraphDeploymentID, uint256 _tokensIn) private view returns (uint256) { - // Get curation pool tokens and signal - CurationPool memory curationPool = pools[_subgraphDeploymentID]; - - // Init curation pool - if (curationPool.tokens == 0) { - require(_tokensIn >= minimumCurationDeposit, "Curation deposit is below minimum required"); - return - BancorFormula(bondingCurve) - .calculatePurchaseReturn( - SIGNAL_PER_MINIMUM_DEPOSIT, - minimumCurationDeposit, - defaultReserveRatio, - _tokensIn.sub(minimumCurationDeposit) - ) - .add(SIGNAL_PER_MINIMUM_DEPOSIT); - } - - return - BancorFormula(bondingCurve).calculatePurchaseReturn( - getCurationPoolSignal(_subgraphDeploymentID), - curationPool.tokens, - curationPool.reserveRatio, - _tokensIn - ); - } - - /** - * @notice Calculate number of tokens to get when burning signal from a curation pool. - * @param _subgraphDeploymentID Subgraph deployment to burn signal - * @param _signalIn Amount of signal to burn - * @return Amount of tokens to get for the specified amount of signal - */ - function signalToTokens(bytes32 _subgraphDeploymentID, uint256 _signalIn) public view override returns (uint256) { - CurationPool memory curationPool = pools[_subgraphDeploymentID]; - uint256 curationPoolSignal = getCurationPoolSignal(_subgraphDeploymentID); - require(curationPool.tokens != 0, "Subgraph deployment must be curated to perform calculations"); - require(curationPoolSignal >= _signalIn, "Signal must be above or equal to signal issued in the curation pool"); - - return - BancorFormula(bondingCurve).calculateSaleReturn( - curationPoolSignal, - curationPool.tokens, - curationPool.reserveRatio, - _signalIn - ); - } - - /** - * @notice Update the default reserver ratio to `_defaultReserveRatio` - * @param _defaultReserveRatio Reserve ratio (in PPM) - */ - function _setDefaultReserveRatio(uint32 _defaultReserveRatio) private { - // Reserve Ratio must be within 0% to 100% (inclusive, in PPM) - require(_defaultReserveRatio != 0, "Default reserve ratio must be > 0"); - require(_defaultReserveRatio <= MAX_PPM, "Default reserve ratio cannot be higher than MAX_PPM"); - - defaultReserveRatio = _defaultReserveRatio; - emit ParameterUpdated("defaultReserveRatio"); - } - - /** - * @notice Update the minimum deposit amount to `_minimumCurationDeposit` - * @param _minimumCurationDeposit Minimum amount of tokens required deposit - */ - function _setMinimumCurationDeposit(uint256 _minimumCurationDeposit) private { - require(_minimumCurationDeposit != 0, "Minimum curation deposit cannot be 0"); - - minimumCurationDeposit = _minimumCurationDeposit; - emit ParameterUpdated("minimumCurationDeposit"); - } - - /** - * @notice Internal: Set the curation tax percentage (in PPM) to charge when a curator deposits GRT tokens. - * @param _percentage Curation tax charged when depositing GRT tokens in PPM - */ - function _setCurationTaxPercentage(uint32 _percentage) private { - require(_percentage <= MAX_PPM, "Curation tax percentage must be below or equal to MAX_PPM"); - - curationTaxPercentage = _percentage; - emit ParameterUpdated("curationTaxPercentage"); - } - - /** - * @notice Internal: Set the master copy to use as clones for the curation token. - * @param _curationTokenMaster Address of implementation contract to use for curation tokens - */ - function _setCurationTokenMaster(address _curationTokenMaster) private { - require(_curationTokenMaster != address(0), "Token master must be non-empty"); - require(AddressUpgradeable.isContract(_curationTokenMaster), "Token master must be a contract"); - - curationTokenMaster = _curationTokenMaster; - emit ParameterUpdated("curationTokenMaster"); - } - - /** - * @notice Triggers an update of rewards due to a change in signal. - * @param _subgraphDeploymentID Subgraph deployment updated - */ - function _updateRewards(bytes32 _subgraphDeploymentID) private { - IRewardsManager rewardsManager = rewardsManager(); - if (address(rewardsManager) != address(0)) { - rewardsManager.onSubgraphSignalUpdate(_subgraphDeploymentID); - } - } -} diff --git a/packages/contracts/contracts/discovery/L1GNS.sol b/packages/contracts/contracts/discovery/L1GNS.sol deleted file mode 100644 index 3441d05fa..000000000 --- a/packages/contracts/contracts/discovery/L1GNS.sol +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -import { SafeMathUpgradeable } from "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; - -import { GNS } from "./GNS.sol"; - -import { ITokenGateway } from "@graphprotocol/interfaces/contracts/contracts/arbitrum/ITokenGateway.sol"; -import { IL2GNS } from "@graphprotocol/interfaces/contracts/contracts/l2/discovery/IL2GNS.sol"; -import { IGraphToken } from "@graphprotocol/interfaces/contracts/contracts/token/IGraphToken.sol"; -import { L1GNSV1Storage } from "./L1GNSStorage.sol"; - -/** - * @title L1GNS - * @author Edge & Node - * @notice The Graph Name System contract provides a decentralized naming system for subgraphs - * used in the scope of the Graph Network. It translates Subgraphs into Subgraph Versions. - * Each version is associated with a Subgraph Deployment. The contract has no knowledge of - * human-readable names. All human readable names emitted in events. - * The contract implements a multicall behaviour to support batching multiple calls in a single - * transaction. - * This L1GNS variant includes some functions to allow transferring subgraphs to L2. - */ -contract L1GNS is GNS, L1GNSV1Storage { - using SafeMathUpgradeable for uint256; - - /** - * @notice Emitted when a subgraph was sent to L2 through the bridge - * @param _subgraphID ID of the subgraph being transferred - * @param _l1Owner Address of the subgraph owner on L1 - * @param _l2Owner Address that will own the subgraph on L2 - * @param _tokens Amount of tokens transferred with the subgraph - */ - event SubgraphSentToL2( - uint256 indexed _subgraphID, - address indexed _l1Owner, - address indexed _l2Owner, - uint256 _tokens - ); - - /** - * @notice Emitted when a curator's balance for a subgraph was sent to L2 - * @param _subgraphID ID of the subgraph - * @param _l1Curator Address of the curator on L1 - * @param _l2Beneficiary Address that will receive the tokens on L2 - * @param _tokens Amount of tokens transferred - */ - event CuratorBalanceSentToL2( - uint256 indexed _subgraphID, - address indexed _l1Curator, - address indexed _l2Beneficiary, - uint256 _tokens - ); - - /** - * @notice Send a subgraph's data and tokens to L2 - * @dev Use the Arbitrum SDK to estimate the L2 retryable ticket parameters. - * Note that any L2 gas/fee refunds will be lost, so the function only accepts - * the exact amount of ETH to cover _maxSubmissionCost + _maxGas * _gasPriceBid - * @param _subgraphID Subgraph ID - * @param _l2Owner Address that will own the subgraph in L2 (could be the L1 owner, but could be different if the L1 owner is an L1 contract) - * @param _maxGas Max gas to use for the L2 retryable ticket - * @param _gasPriceBid Gas price bid for the L2 retryable ticket - * @param _maxSubmissionCost Max submission cost for the L2 retryable ticket - */ - function sendSubgraphToL2( - uint256 _subgraphID, - address _l2Owner, - uint256 _maxGas, - uint256 _gasPriceBid, - uint256 _maxSubmissionCost - ) external payable notPartialPaused { - require(!subgraphTransferredToL2[_subgraphID], "ALREADY_DONE"); - require(msg.value == _maxSubmissionCost.add(_maxGas.mul(_gasPriceBid)), "INVALID_ETH_VALUE"); - - SubgraphData storage subgraphData = _getSubgraphOrRevert(_subgraphID); - // This is just like onlySubgraphAuth, but we want it to run after the subgraphTransferredToL2 check - // to revert with a nicer message in that case: - require(ownerOf(_subgraphID) == msg.sender, "GNS: Must be authorized"); - subgraphTransferredToL2[_subgraphID] = true; - - uint256 curationTokens = curation().burn(subgraphData.subgraphDeploymentID, subgraphData.vSignal, 0); - subgraphData.disabled = true; - subgraphData.vSignal = 0; - - // We send only the subgraph owner's tokens and nsignal to L2, - // and for everyone else we set the withdrawableGRT so that they can choose - // to withdraw or transfer their signal. - uint256 ownerNSignal = subgraphData.curatorNSignal[msg.sender]; - uint256 totalSignal = subgraphData.nSignal; - - // Get owner share of tokens to be sent to L2 - uint256 tokensForL2 = ownerNSignal.mul(curationTokens).div(totalSignal); - // This leaves the subgraph as if it was deprecated, - // so other curators can withdraw: - subgraphData.curatorNSignal[msg.sender] = 0; - subgraphData.nSignal = totalSignal.sub(ownerNSignal); - subgraphData.withdrawableGRT = curationTokens.sub(tokensForL2); - - bytes memory extraData = abi.encode(uint8(IL2GNS.L1MessageCodes.RECEIVE_SUBGRAPH_CODE), _subgraphID, _l2Owner); - - _sendTokensAndMessageToL2GNS(tokensForL2, _maxGas, _gasPriceBid, _maxSubmissionCost, extraData); - - subgraphData.__DEPRECATED_reserveRatio = 0; - _burnNFT(_subgraphID); - emit SubgraphSentToL2(_subgraphID, msg.sender, _l2Owner, tokensForL2); - } - - /** - * @notice Send the balance for a curator's signal in a subgraph that was - * transferred to L2, using the L1GraphTokenGateway. - * The balance will be claimed for a beneficiary address, as this method can be - * used by curators that use a contract address in L1 that may not exist in L2. - * This will set the curator's signal on L1 to zero, so the caller must ensure - * that the retryable ticket is redeemed before expiration, or the signal will be lost. - * It is up to the caller to verify that the subgraph transfer was finished in L2, - * but if it wasn't, the tokens will be sent to the beneficiary in L2. - * Note that any L2 gas/fee refunds will be lost, so the function only accepts - * the exact amount of ETH to cover _maxSubmissionCost + _maxGas * _gasPriceBid. - * @dev Use the Arbitrum SDK to estimate the L2 retryable ticket parameters. - * @param _subgraphID Subgraph ID - * @param _beneficiary Address that will receive the tokens in L2 - * @param _maxGas Max gas to use for the L2 retryable ticket - * @param _gasPriceBid Gas price bid for the L2 retryable ticket - * @param _maxSubmissionCost Max submission cost for the L2 retryable ticket - */ - function sendCuratorBalanceToBeneficiaryOnL2( - uint256 _subgraphID, - address _beneficiary, - uint256 _maxGas, - uint256 _gasPriceBid, - uint256 _maxSubmissionCost - ) external payable notPartialPaused { - require(subgraphTransferredToL2[_subgraphID], "!TRANSFERRED"); - require(msg.value == _maxSubmissionCost.add(_maxGas.mul(_gasPriceBid)), "INVALID_ETH_VALUE"); - // The Arbitrum bridge will check this too, we just check here for an early exit - require(_maxSubmissionCost != 0, "NO_SUBMISSION_COST"); - - SubgraphData storage subgraphData = _getSubgraphData(_subgraphID); - uint256 curatorNSignal = subgraphData.curatorNSignal[msg.sender]; - require(curatorNSignal != 0, "NO_SIGNAL"); - uint256 subgraphNSignal = subgraphData.nSignal; - require(subgraphNSignal != 0, "NO_SUBGRAPH_SIGNAL"); - - uint256 withdrawableGRT = subgraphData.withdrawableGRT; - uint256 tokensForL2 = curatorNSignal.mul(withdrawableGRT).div(subgraphNSignal); - bytes memory extraData = abi.encode( - uint8(IL2GNS.L1MessageCodes.RECEIVE_CURATOR_BALANCE_CODE), - _subgraphID, - _beneficiary - ); - - // Set the subgraph as if the curator had withdrawn their tokens - subgraphData.curatorNSignal[msg.sender] = 0; - subgraphData.nSignal = subgraphNSignal.sub(curatorNSignal); - subgraphData.withdrawableGRT = withdrawableGRT.sub(tokensForL2); - - // Send the tokens and data to L2 using the L1GraphTokenGateway - _sendTokensAndMessageToL2GNS(tokensForL2, _maxGas, _gasPriceBid, _maxSubmissionCost, extraData); - emit CuratorBalanceSentToL2(_subgraphID, msg.sender, _beneficiary, tokensForL2); - } - - /** - * @notice Sends a message to the L2GNS with some extra data, - * also sending some tokens, using the L1GraphTokenGateway. - * @param _tokens Amount of tokens to send to L2 - * @param _maxGas Max gas to use for the L2 retryable ticket - * @param _gasPriceBid Gas price bid for the L2 retryable ticket - * @param _maxSubmissionCost Max submission cost for the L2 retryable ticket - * @param _extraData Extra data for the callhook on L2GNS - */ - function _sendTokensAndMessageToL2GNS( - uint256 _tokens, - uint256 _maxGas, - uint256 _gasPriceBid, - uint256 _maxSubmissionCost, - bytes memory _extraData - ) internal { - bytes memory data = abi.encode(_maxSubmissionCost, _extraData); - IGraphToken grt = graphToken(); - ITokenGateway gateway = graphTokenGateway(); - grt.approve(address(gateway), _tokens); - gateway.outboundTransfer{ value: msg.value }( - address(grt), - counterpartGNSAddress, - _tokens, - _maxGas, - _gasPriceBid, - data - ); - } -} diff --git a/packages/contracts/contracts/discovery/L1GNSStorage.sol b/packages/contracts/contracts/discovery/L1GNSStorage.sol deleted file mode 100644 index 72af676f2..000000000 --- a/packages/contracts/contracts/discovery/L1GNSStorage.sol +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable named-parameters-mapping - -pragma solidity ^0.7.6; -pragma abicoder v2; - -/** - * @title L1GNSV1Storage - * @author Edge & Node - * @notice This contract holds all the L1-specific storage variables for the L1GNS contract, version 1 - * @dev When adding new versions, make sure to move the gap to the new version and - * reduce the size of the gap accordingly. - */ -abstract contract L1GNSV1Storage { - /// @notice True for subgraph IDs that have been transferred to L2 - mapping(uint256 => bool) public subgraphTransferredToL2; - /// @dev Storage gap to keep storage slots fixed in future versions - uint256[50] private __gap; -} diff --git a/packages/contracts/contracts/discovery/ServiceRegistry.sol b/packages/contracts/contracts/discovery/ServiceRegistry.sol deleted file mode 100644 index 32db1fe1b..000000000 --- a/packages/contracts/contracts/discovery/ServiceRegistry.sol +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -import { Managed } from "../governance/Managed.sol"; -import { GraphUpgradeable } from "../upgrades/GraphUpgradeable.sol"; - -import { ServiceRegistryV1Storage } from "./ServiceRegistryStorage.sol"; -import { IServiceRegistry } from "@graphprotocol/interfaces/contracts/contracts/discovery/IServiceRegistry.sol"; - -/** - * @title ServiceRegistry contract - * @author Edge & Node - * @notice This contract supports the service discovery process by allowing indexers to - * register their service url and any other relevant information. - */ -contract ServiceRegistry is ServiceRegistryV1Storage, GraphUpgradeable, IServiceRegistry { - // -- Events -- - - /** - * @notice Emitted when an indexer registers their service - * @param indexer Address of the indexer - * @param url URL of the indexer service - * @param geohash Geohash of the indexer service location - */ - event ServiceRegistered(address indexed indexer, string url, string geohash); - - /** - * @notice Emitted when an indexer unregisters their service - * @param indexer Address of the indexer - */ - event ServiceUnregistered(address indexed indexer); - - /** - * @notice Check if the caller is authorized (indexer or operator) - * @param _indexer Address of the indexer to check authorization for - * @return True if the caller is authorized, false otherwise - */ - function _isAuth(address _indexer) internal view returns (bool) { - return msg.sender == _indexer || staking().isOperator(msg.sender, _indexer) == true; - } - - /** - * @notice Initialize this contract. - * @param _controller Address of the controller contract - */ - function initialize(address _controller) external onlyImpl { - Managed._initialize(_controller); - } - - /** - * @inheritdoc IServiceRegistry - */ - function register(string calldata _url, string calldata _geohash) external override { - _register(msg.sender, _url, _geohash); - } - - /** - * @inheritdoc IServiceRegistry - */ - function registerFor(address _indexer, string calldata _url, string calldata _geohash) external override { - _register(_indexer, _url, _geohash); - } - - /** - * @notice Internal: Register an indexer service - * @param _indexer Address of the indexer - * @param _url URL of the indexer service - * @param _geohash Geohash of the indexer service location - */ - function _register(address _indexer, string calldata _url, string calldata _geohash) private { - require(_isAuth(_indexer), "!auth"); - require(bytes(_url).length > 0, "Service must specify a URL"); - - services[_indexer] = IndexerService(_url, _geohash); - - emit ServiceRegistered(_indexer, _url, _geohash); - } - - /** - * @inheritdoc IServiceRegistry - */ - function unregister() external override { - _unregister(msg.sender); - } - - /** - * @inheritdoc IServiceRegistry - */ - function unregisterFor(address _indexer) external override { - _unregister(_indexer); - } - - /** - * @notice Unregister an indexer service - * @param _indexer Address of the indexer - */ - function _unregister(address _indexer) private { - require(_isAuth(_indexer), "!auth"); - require(isRegistered(_indexer), "Service already unregistered"); - - delete services[_indexer]; - emit ServiceUnregistered(_indexer); - } - - /** - * @inheritdoc IServiceRegistry - */ - function isRegistered(address _indexer) public view override returns (bool) { - return bytes(services[_indexer].url).length > 0; - } -} diff --git a/packages/contracts/contracts/discovery/ServiceRegistryStorage.sol b/packages/contracts/contracts/discovery/ServiceRegistryStorage.sol deleted file mode 100644 index 4ad8a7359..000000000 --- a/packages/contracts/contracts/discovery/ServiceRegistryStorage.sol +++ /dev/null @@ -1,22 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable named-parameters-mapping - -pragma solidity ^0.7.6; - -import { Managed } from "../governance/Managed.sol"; - -import { IServiceRegistry } from "@graphprotocol/interfaces/contracts/contracts/discovery/IServiceRegistry.sol"; - -/** - * @title Service Registry Storage V1 - * @author Edge & Node - * @notice Storage contract for the Service Registry - */ -contract ServiceRegistryV1Storage is Managed { - // -- State -- - - /// @notice Mapping of indexer addresses to their service information - mapping(address => IServiceRegistry.IndexerService) public services; -} diff --git a/packages/contracts/contracts/discovery/erc1056/EthereumDIDRegistry.sol b/packages/contracts/contracts/discovery/erc1056/EthereumDIDRegistry.sol deleted file mode 100644 index 76c1a41f9..000000000 --- a/packages/contracts/contracts/discovery/erc1056/EthereumDIDRegistry.sol +++ /dev/null @@ -1,436 +0,0 @@ -/* -Original Author: https://github.com/uport-project/ethr-did-registry - -This contract is included in graphprotocol/contracts for testing purposes -The contract is already deployed on mainnet: -https://etherscan.io/address/0xdca7ef03e98e0dc2b855be647c39abe984fcf21b#code - -As well as all testnets -*/ - -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.7.6; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable gas-increment-by-one, gas-indexed-events, gas-small-strings -// solhint-disable named-parameters-mapping - -/** - * @title Ethereum DID Registry - * @author Edge & Node - * @notice Registry for Ethereum Decentralized Identifiers (DIDs) - */ -contract EthereumDIDRegistry { - /// @notice Mapping of identity addresses to their owners - mapping(address => address) public owners; - /// @notice Mapping of identity addresses to delegate types to delegate addresses to validity periods - mapping(address => mapping(bytes32 => mapping(address => uint256))) public delegates; - /// @notice Mapping of identity addresses to their last change block numbers - mapping(address => uint256) public changed; - /// @notice Mapping of identity addresses to their nonce values - mapping(address => uint256) public nonce; - - /** - * @notice Modifier to restrict access to identity owners only - * @param identity The identity address - * @param actor The address performing the action - */ - modifier onlyOwner(address identity, address actor) { - require(actor == identityOwner(identity), "Caller must be the identity owner"); - _; - } - - /** - * @notice Emitted when a DID owner is changed - * @param identity The identity address - * @param owner The new owner address - * @param previousChange Block number of the previous change - */ - event DIDOwnerChanged(address indexed identity, address owner, uint256 previousChange); - - /** - * @notice Emitted when a DID delegate is changed - * @param identity The identity address - * @param delegateType The type of delegate - * @param delegate The delegate address - * @param validTo Timestamp until which the delegate is valid - * @param previousChange Block number of the previous change - */ - event DIDDelegateChanged( - address indexed identity, - bytes32 delegateType, - address delegate, - uint256 validTo, - uint256 previousChange - ); - - /** - * @notice Emitted when a DID attribute is changed - * @param identity The identity address - * @param name The attribute name - * @param value The attribute value - * @param validTo Timestamp until which the attribute is valid - * @param previousChange Block number of the previous change - */ - event DIDAttributeChanged( - address indexed identity, - bytes32 name, - bytes value, - uint256 validTo, - uint256 previousChange - ); - - /** - * @notice Get the owner of an identity - * @param identity The identity address - * @return The address of the identity owner - */ - function identityOwner(address identity) public view returns (address) { - address owner = owners[identity]; - if (owner != address(0)) { - return owner; - } - return identity; - } - - /** - * @notice Verify signature and return signer address - * @param identity The identity address - * @param sigV Recovery ID of the signature - * @param sigR R component of the signature - * @param sigS S component of the signature - * @param hash Hash that was signed - * @return The address of the signer - */ - function checkSignature( - address identity, - uint8 sigV, - bytes32 sigR, - bytes32 sigS, - bytes32 hash - ) internal returns (address) { - address signer = ecrecover(hash, sigV, sigR, sigS); - require(signer == identityOwner(identity), "Signer must be the identity owner"); - nonce[signer]++; - return signer; - } - - /** - * @notice Check if a delegate is valid for an identity - * @param identity The identity address - * @param delegateType The type of delegate - * @param delegate The delegate address - * @return True if the delegate is valid, false otherwise - */ - function validDelegate(address identity, bytes32 delegateType, address delegate) public view returns (bool) { - uint256 validity = delegates[identity][keccak256(abi.encode(delegateType))][delegate]; - /* solium-disable-next-line security/no-block-members*/ - return (validity > block.timestamp); - } - - /** - * @notice Internal function to change the owner of an identity - * @param identity The identity address - * @param actor The address performing the action - * @param newOwner The new owner address - */ - function changeOwner(address identity, address actor, address newOwner) internal onlyOwner(identity, actor) { - owners[identity] = newOwner; - emit DIDOwnerChanged(identity, newOwner, changed[identity]); - changed[identity] = block.number; - } - - /** - * @notice Change the owner of an identity - * @param identity The identity address - * @param newOwner The new owner address - */ - function changeOwner(address identity, address newOwner) public { - changeOwner(identity, msg.sender, newOwner); - } - - /** - * @notice Change the owner of an identity using a signed message - * @param identity The identity address - * @param sigV Recovery ID of the signature - * @param sigR R component of the signature - * @param sigS S component of the signature - * @param newOwner The new owner address - */ - function changeOwnerSigned(address identity, uint8 sigV, bytes32 sigR, bytes32 sigS, address newOwner) public { - bytes32 hash = keccak256( - abi.encodePacked( - bytes1(0x19), - bytes1(0), - this, - nonce[identityOwner(identity)], - identity, - "changeOwner", - newOwner - ) - ); - changeOwner(identity, checkSignature(identity, sigV, sigR, sigS, hash), newOwner); - } - - /** - * @notice Internal function to add a delegate for an identity - * @param identity The identity address - * @param actor The address performing the action - * @param delegateType The type of delegate - * @param delegate The delegate address - * @param validity The validity period in seconds - */ - function addDelegate( - address identity, - address actor, - bytes32 delegateType, - address delegate, - uint256 validity - ) internal onlyOwner(identity, actor) { - /* solium-disable-next-line security/no-block-members*/ - delegates[identity][keccak256(abi.encode(delegateType))][delegate] = block.timestamp + validity; - emit DIDDelegateChanged( - identity, - delegateType, - delegate, - /* solium-disable-next-line security/no-block-members*/ - block.timestamp + validity, - changed[identity] - ); - changed[identity] = block.number; - } - - /** - * @notice Add a delegate for an identity - * @param identity The identity to add a delegate for - * @param delegateType The type of delegate - * @param delegate The address of the delegate - * @param validity The validity period in seconds - */ - function addDelegate(address identity, bytes32 delegateType, address delegate, uint256 validity) public { - addDelegate(identity, msg.sender, delegateType, delegate, validity); - } - - /** - * @notice Add a delegate for an identity using a signed message - * @param identity The identity to add a delegate for - * @param sigV The recovery id of the signature - * @param sigR The r component of the signature - * @param sigS The s component of the signature - * @param delegateType The type of delegate - * @param delegate The address of the delegate - * @param validity The validity period in seconds - */ - function addDelegateSigned( - address identity, - uint8 sigV, - bytes32 sigR, - bytes32 sigS, - bytes32 delegateType, - address delegate, - uint256 validity - ) public { - bytes32 hash = keccak256( - abi.encodePacked( - bytes1(0x19), - bytes1(0), - this, - nonce[identityOwner(identity)], - identity, - "addDelegate", - delegateType, - delegate, - validity - ) - ); - addDelegate(identity, checkSignature(identity, sigV, sigR, sigS, hash), delegateType, delegate, validity); - } - - /** - * @notice Internal function to revoke a delegate for an identity - * @param identity The identity address - * @param actor The address performing the action - * @param delegateType The type of delegate - * @param delegate The delegate address - */ - function revokeDelegate( - address identity, - address actor, - bytes32 delegateType, - address delegate - ) internal onlyOwner(identity, actor) { - /* solium-disable-next-line security/no-block-members*/ - delegates[identity][keccak256(abi.encode(delegateType))][delegate] = block.timestamp; - /* solium-disable-next-line security/no-block-members*/ - emit DIDDelegateChanged(identity, delegateType, delegate, block.timestamp, changed[identity]); - changed[identity] = block.number; - } - - /** - * @notice Revoke a delegate for an identity - * @param identity The identity to revoke a delegate for - * @param delegateType The type of delegate - * @param delegate The address of the delegate - */ - function revokeDelegate(address identity, bytes32 delegateType, address delegate) public { - revokeDelegate(identity, msg.sender, delegateType, delegate); - } - - /** - * @notice Revoke a delegate for an identity using a signed message - * @param identity The identity to revoke a delegate for - * @param sigV The recovery id of the signature - * @param sigR The r component of the signature - * @param sigS The s component of the signature - * @param delegateType The type of delegate - * @param delegate The address of the delegate - */ - function revokeDelegateSigned( - address identity, - uint8 sigV, - bytes32 sigR, - bytes32 sigS, - bytes32 delegateType, - address delegate - ) public { - bytes32 hash = keccak256( - abi.encodePacked( - bytes1(0x19), - bytes1(0), - this, - nonce[identityOwner(identity)], - identity, - "revokeDelegate", - delegateType, - delegate - ) - ); - revokeDelegate(identity, checkSignature(identity, sigV, sigR, sigS, hash), delegateType, delegate); - } - - /** - * @notice Internal function to set an attribute for an identity - * @param identity The identity address - * @param actor The address performing the action - * @param name The attribute name - * @param value The attribute value - * @param validity The validity period in seconds - */ - function setAttribute( - address identity, - address actor, - bytes32 name, - bytes memory value, - uint256 validity - ) internal onlyOwner(identity, actor) { - /* solium-disable-next-line security/no-block-members*/ - emit DIDAttributeChanged(identity, name, value, block.timestamp + validity, changed[identity]); - changed[identity] = block.number; - } - - /** - * @notice Set an attribute for an identity - * @param identity The identity to set an attribute for - * @param name The name of the attribute - * @param value The value of the attribute - * @param validity The validity period in seconds - */ - function setAttribute(address identity, bytes32 name, bytes memory value, uint256 validity) public { - setAttribute(identity, msg.sender, name, value, validity); - } - - /** - * @notice Set an attribute for an identity using a signed message - * @param identity The identity to set an attribute for - * @param sigV The recovery id of the signature - * @param sigR The r component of the signature - * @param sigS The s component of the signature - * @param name The name of the attribute - * @param value The value of the attribute - * @param validity The validity period in seconds - */ - function setAttributeSigned( - address identity, - uint8 sigV, - bytes32 sigR, - bytes32 sigS, - bytes32 name, - bytes memory value, - uint256 validity - ) public { - bytes32 hash = keccak256( - abi.encodePacked( - bytes1(0x19), - bytes1(0), - this, - nonce[identityOwner(identity)], - identity, - "setAttribute", - name, - value, - validity - ) - ); - setAttribute(identity, checkSignature(identity, sigV, sigR, sigS, hash), name, value, validity); - } - - /** - * @notice Internal function to revoke an attribute for an identity - * @param identity The identity address - * @param actor The address performing the action - * @param name The attribute name - * @param value The attribute value - */ - function revokeAttribute( - address identity, - address actor, - bytes32 name, - bytes memory value - ) internal onlyOwner(identity, actor) { - emit DIDAttributeChanged(identity, name, value, 0, changed[identity]); - changed[identity] = block.number; - } - - /** - * @notice Revoke an attribute for an identity - * @param identity The identity to revoke an attribute for - * @param name The name of the attribute - * @param value The value of the attribute - */ - function revokeAttribute(address identity, bytes32 name, bytes memory value) public { - revokeAttribute(identity, msg.sender, name, value); - } - - /** - * @notice Revoke an attribute for an identity using a signed message - * @param identity The identity to revoke an attribute for - * @param sigV The recovery id of the signature - * @param sigR The r component of the signature - * @param sigS The s component of the signature - * @param name The name of the attribute - * @param value The value of the attribute - */ - function revokeAttributeSigned( - address identity, - uint8 sigV, - bytes32 sigR, - bytes32 sigS, - bytes32 name, - bytes memory value - ) public { - bytes32 hash = keccak256( - abi.encodePacked( - bytes1(0x19), - bytes1(0), - this, - nonce[identityOwner(identity)], - identity, - "revokeAttribute", - name, - value - ) - ); - revokeAttribute(identity, checkSignature(identity, sigV, sigR, sigS, hash), name, value); - } -} diff --git a/packages/contracts/contracts/disputes/DisputeManager.sol b/packages/contracts/contracts/disputes/DisputeManager.sol deleted file mode 100644 index 9ef426453..000000000 --- a/packages/contracts/contracts/disputes/DisputeManager.sol +++ /dev/null @@ -1,783 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable gas-small-strings, gas-strict-inequalities - -import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; -import { ECDSA } from "@openzeppelin/contracts/cryptography/ECDSA.sol"; - -import { Managed } from "../governance/Managed.sol"; -import { GraphUpgradeable } from "../upgrades/GraphUpgradeable.sol"; -import { TokenUtils } from "../utils/TokenUtils.sol"; -import { IStaking } from "@graphprotocol/interfaces/contracts/contracts/staking/IStaking.sol"; - -import { DisputeManagerV1Storage } from "./DisputeManagerStorage.sol"; -import { IDisputeManager } from "@graphprotocol/interfaces/contracts/contracts/disputes/IDisputeManager.sol"; - -/** - * @title DisputeManager - * @author Edge & Node - * @notice Provides a way to align the incentives of participants by having slashing as deterrent - * for incorrect behaviour. - * - * There are two types of disputes that can be created: Query disputes and Indexing disputes. - * - * Query Disputes: - * Graph nodes receive queries and return responses with signed receipts called attestations. - * An attestation can be disputed if the consumer thinks the query response was invalid. - * Indexers use the derived private key for an allocation to sign attestations. - * - * Indexing Disputes: - * Indexers present a Proof of Indexing (POI) when they close allocations to prove - * they were indexing a subgraph. The Staking contract emits that proof with the format - * keccak256(indexer.address, POI). - * Any challenger can dispute the validity of a POI by submitting a dispute to this contract - * along with a deposit. - * - * Arbitration: - * Disputes can only be accepted, rejected or drawn by the arbitrator role that can be delegated - * to a EOA or DAO. - */ -contract DisputeManager is DisputeManagerV1Storage, GraphUpgradeable, IDisputeManager { - using SafeMath for uint256; - - // -- EIP-712 -- - - /// @dev EIP-712 domain type hash for signature verification - bytes32 private constant DOMAIN_TYPE_HASH = - keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract,bytes32 salt)"); - /// @dev EIP-712 domain name hash - bytes32 private constant DOMAIN_NAME_HASH = keccak256("Graph Protocol"); - /// @dev EIP-712 domain version hash - bytes32 private constant DOMAIN_VERSION_HASH = keccak256("0"); - /// @dev EIP-712 domain salt for uniqueness - bytes32 private constant DOMAIN_SALT = 0xa070ffb1cd7409649bf77822cce74495468e06dbfaef09556838bf188679b9c2; - /// @dev EIP-712 receipt type hash for attestation verification - bytes32 private constant RECEIPT_TYPE_HASH = - keccak256("Receipt(bytes32 requestCID,bytes32 responseCID,bytes32 subgraphDeploymentID)"); - - // -- Constants -- - - /// @dev Total size of attestation in bytes (receipt + signature) - uint256 private constant ATTESTATION_SIZE_BYTES = RECEIPT_SIZE_BYTES + SIG_SIZE_BYTES; - /// @dev Size of receipt in bytes - uint256 private constant RECEIPT_SIZE_BYTES = 96; - - /// @dev Length of signature R component in bytes - uint256 private constant SIG_R_LENGTH = 32; - /// @dev Length of signature S component in bytes - uint256 private constant SIG_S_LENGTH = 32; - /// @dev Length of signature V component in bytes - uint256 private constant SIG_V_LENGTH = 1; - /// @dev Offset of signature R component in attestation data - uint256 private constant SIG_R_OFFSET = RECEIPT_SIZE_BYTES; - /// @dev Offset of signature S component in attestation data - uint256 private constant SIG_S_OFFSET = RECEIPT_SIZE_BYTES + SIG_R_LENGTH; - /// @dev Offset of signature V component in attestation data - uint256 private constant SIG_V_OFFSET = RECEIPT_SIZE_BYTES + SIG_R_LENGTH + SIG_S_LENGTH; - /// @dev Total size of signature in bytes - uint256 private constant SIG_SIZE_BYTES = SIG_R_LENGTH + SIG_S_LENGTH + SIG_V_LENGTH; - - /// @dev Length of uint8 type in bytes - uint256 private constant UINT8_BYTE_LENGTH = 1; - /// @dev Length of bytes32 type in bytes - uint256 private constant BYTES32_BYTE_LENGTH = 32; - - /// @dev Maximum percentage in parts per million (100%) - uint256 private constant MAX_PPM = 1000000; // 100% in parts per million - - // -- Events -- - - /** - * @notice Emitted when a query dispute is created for `subgraphDeploymentID` and `indexer` - * by `fisherman`. - * The event emits the amount of `tokens` deposited by the fisherman and `attestation` submitted. - * @param disputeID ID of the dispute - * @param indexer Address of the indexer being disputed - * @param fisherman Address of the fisherman creating the dispute - * @param tokens Amount of tokens deposited by the fisherman - * @param subgraphDeploymentID Subgraph deployment ID being disputed - * @param attestation Attestation data submitted - */ - event QueryDisputeCreated( - bytes32 indexed disputeID, - address indexed indexer, - address indexed fisherman, - uint256 tokens, - bytes32 subgraphDeploymentID, - bytes attestation - ); - - /** - * @notice Emitted when an indexing dispute is created for `allocationID` and `indexer` - * by `fisherman`. - * The event emits the amount of `tokens` deposited by the fisherman. - * @param disputeID ID of the dispute - * @param indexer Address of the indexer being disputed - * @param fisherman Address of the fisherman creating the dispute - * @param tokens Amount of tokens deposited by the fisherman - * @param allocationID Allocation ID being disputed - */ - event IndexingDisputeCreated( - bytes32 indexed disputeID, - address indexed indexer, - address indexed fisherman, - uint256 tokens, - address allocationID - ); - - /** - * @notice Emitted when arbitrator accepts a `disputeID` to `indexer` created by `fisherman`. - * The event emits the amount `tokens` transferred to the fisherman, the deposit plus reward. - * @param disputeID ID of the dispute - * @param indexer Address of the indexer being disputed - * @param fisherman Address of the fisherman who created the dispute - * @param tokens Amount of tokens transferred to the fisherman (deposit plus reward) - */ - event DisputeAccepted( - bytes32 indexed disputeID, - address indexed indexer, - address indexed fisherman, - uint256 tokens - ); - - /** - * @notice Emitted when arbitrator rejects a `disputeID` for `indexer` created by `fisherman`. - * The event emits the amount `tokens` burned from the fisherman deposit. - * @param disputeID ID of the dispute - * @param indexer Address of the indexer being disputed - * @param fisherman Address of the fisherman who created the dispute - * @param tokens Amount of tokens burned from the fisherman deposit - */ - event DisputeRejected( - bytes32 indexed disputeID, - address indexed indexer, - address indexed fisherman, - uint256 tokens - ); - - /** - * @notice Emitted when arbitrator draw a `disputeID` for `indexer` created by `fisherman`. - * The event emits the amount `tokens` used as deposit and returned to the fisherman. - * @param disputeID ID of the dispute - * @param indexer Address of the indexer being disputed - * @param fisherman Address of the fisherman who created the dispute - * @param tokens Amount of tokens used as deposit and returned to the fisherman - */ - event DisputeDrawn(bytes32 indexed disputeID, address indexed indexer, address indexed fisherman, uint256 tokens); - - /** - * @notice Emitted when two disputes are in conflict to link them. - * This event will be emitted after each DisputeCreated event is emitted - * for each of the individual disputes. - * @param disputeID1 ID of the first dispute - * @param disputeID2 ID of the second dispute - */ - event DisputeLinked(bytes32 indexed disputeID1, bytes32 indexed disputeID2); - - // -- Modifiers -- - - /** - * @notice Internal function to check if the caller is the arbitrator - */ - function _onlyArbitrator() internal view { - require(msg.sender == arbitrator, "Caller is not the Arbitrator"); - } - - /** - * @dev Check if the caller is the arbitrator. - */ - modifier onlyArbitrator() { - _onlyArbitrator(); - _; - } - - /** - * @dev Check if the dispute exists and is pending - * @param _disputeID ID of the dispute to check - */ - modifier onlyPendingDispute(bytes32 _disputeID) { - require(isDisputeCreated(_disputeID), "Dispute does not exist"); - require(disputes[_disputeID].status == IDisputeManager.DisputeStatus.Pending, "Dispute must be pending"); - _; - } - - // -- Functions -- - - /** - * @notice Initialize this contract. - * @param _controller Controller address - * @param _arbitrator Arbitrator role - * @param _minimumDeposit Minimum deposit required to create a Dispute - * @param _fishermanRewardPercentage Percent of slashed funds for fisherman (ppm) - * @param _qrySlashingPercentage Percentage of indexer stake slashed for query disputes (ppm) - * @param _idxSlashingPercentage Percentage of indexer stake slashed for indexing disputes (ppm) - */ - function initialize( - address _controller, - address _arbitrator, - uint256 _minimumDeposit, - uint32 _fishermanRewardPercentage, - uint32 _qrySlashingPercentage, - uint32 _idxSlashingPercentage - ) external onlyImpl { - Managed._initialize(_controller); - - // Settings - _setArbitrator(_arbitrator); - _setMinimumDeposit(_minimumDeposit); - _setFishermanRewardPercentage(_fishermanRewardPercentage); - _setSlashingPercentage(_qrySlashingPercentage, _idxSlashingPercentage); - - // EIP-712 domain separator - DOMAIN_SEPARATOR = keccak256( - abi.encode( - DOMAIN_TYPE_HASH, - DOMAIN_NAME_HASH, - DOMAIN_VERSION_HASH, - _getChainID(), - address(this), - DOMAIN_SALT - ) - ); - } - - /** - * @inheritdoc IDisputeManager - */ - function setArbitrator(address _arbitrator) external override onlyGovernor { - _setArbitrator(_arbitrator); - } - - /** - * @notice Update the arbitrator to `_arbitrator` - * @param _arbitrator The address of the arbitration contract or party - */ - function _setArbitrator(address _arbitrator) private { - require(_arbitrator != address(0), "Arbitrator must be set"); - arbitrator = _arbitrator; - emit ParameterUpdated("arbitrator"); - } - - /** - * @inheritdoc IDisputeManager - */ - function setMinimumDeposit(uint256 _minimumDeposit) external override onlyGovernor { - _setMinimumDeposit(_minimumDeposit); - } - - /** - * @notice Update the minimum deposit to `_minimumDeposit` Graph Tokens - * @param _minimumDeposit The minimum deposit in Graph Tokens - */ - function _setMinimumDeposit(uint256 _minimumDeposit) private { - require(_minimumDeposit > 0, "Minimum deposit must be set"); - minimumDeposit = _minimumDeposit; - emit ParameterUpdated("minimumDeposit"); - } - - /** - * @inheritdoc IDisputeManager - */ - function setFishermanRewardPercentage(uint32 _percentage) external override onlyGovernor { - _setFishermanRewardPercentage(_percentage); - } - - /** - * @notice Set the percent reward that the fisherman gets when slashing occurs. - * @param _percentage Reward as a percentage of indexer stake - */ - function _setFishermanRewardPercentage(uint32 _percentage) private { - // Must be within 0% to 100% (inclusive) - require(_percentage <= MAX_PPM, "Reward percentage must be below or equal to MAX_PPM"); - fishermanRewardPercentage = _percentage; - emit ParameterUpdated("fishermanRewardPercentage"); - } - - /** - * @inheritdoc IDisputeManager - */ - function setSlashingPercentage(uint32 _qryPercentage, uint32 _idxPercentage) external override onlyGovernor { - _setSlashingPercentage(_qryPercentage, _idxPercentage); - } - - /** - * @notice Internal: Set the percentage used for slashing indexers. - * @param _qryPercentage Percentage slashing for query disputes - * @param _idxPercentage Percentage slashing for indexing disputes - */ - function _setSlashingPercentage(uint32 _qryPercentage, uint32 _idxPercentage) private { - // Must be within 0% to 100% (inclusive) - require( - _qryPercentage <= MAX_PPM && _idxPercentage <= MAX_PPM, - "Slashing percentage must be below or equal to MAX_PPM" - ); - qrySlashingPercentage = _qryPercentage; - idxSlashingPercentage = _idxPercentage; - emit ParameterUpdated("qrySlashingPercentage"); - emit ParameterUpdated("idxSlashingPercentage"); - } - - /** - * @inheritdoc IDisputeManager - */ - function isDisputeCreated(bytes32 _disputeID) public view override returns (bool) { - return disputes[_disputeID].status != DisputeStatus.Null; - } - - /** - * @inheritdoc IDisputeManager - * @dev Encodes a receipt using a domain separator, as described on - * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#specification. - */ - function encodeHashReceipt(Receipt memory _receipt) public view override returns (bytes32) { - return - keccak256( - abi.encodePacked( - "\x19\x01", // EIP-191 encoding pad, EIP-712 version 1 - DOMAIN_SEPARATOR, - keccak256( - abi.encode( - RECEIPT_TYPE_HASH, - _receipt.requestCID, - _receipt.responseCID, - _receipt.subgraphDeploymentID - ) // EIP 712-encoded message hash - ) - ) - ); - } - - /** - * @inheritdoc IDisputeManager - * @dev Everything must match except for the responseID. - */ - function areConflictingAttestations( - Attestation memory _attestation1, - Attestation memory _attestation2 - ) public pure override returns (bool) { - return (_attestation1.requestCID == _attestation2.requestCID && - _attestation1.subgraphDeploymentID == _attestation2.subgraphDeploymentID && - _attestation1.responseCID != _attestation2.responseCID); - } - - /** - * @inheritdoc IDisputeManager - */ - function getAttestationIndexer(Attestation memory _attestation) public view override returns (address) { - // Get attestation signer. Indexers signs with the allocationID - address allocationID = _recoverAttestationSigner(_attestation); - - IStaking.Allocation memory alloc = staking().getAllocation(allocationID); - require(alloc.indexer != address(0), "Indexer cannot be found for the attestation"); - require( - alloc.subgraphDeploymentID == _attestation.subgraphDeploymentID, - "Allocation and attestation subgraphDeploymentID must match" - ); - return alloc.indexer; - } - - /** - * @inheritdoc IDisputeManager - * @dev This function is called by a fisherman that will need to `_deposit` at - * least `minimumDeposit` GRT tokens. - */ - function createQueryDispute(bytes calldata _attestationData, uint256 _deposit) external override returns (bytes32) { - // Get funds from submitter - _pullSubmitterDeposit(_deposit); - - // Create a dispute - return - _createQueryDisputeWithAttestation( - msg.sender, - _deposit, - _parseAttestation(_attestationData), - _attestationData - ); - } - - /** - * @inheritdoc IDisputeManager - */ - function createQueryDisputeConflict( - bytes calldata _attestationData1, - bytes calldata _attestationData2 - ) external override returns (bytes32, bytes32) { - address fisherman = msg.sender; - - // Parse each attestation - Attestation memory attestation1 = _parseAttestation(_attestationData1); - Attestation memory attestation2 = _parseAttestation(_attestationData2); - - // Test that attestations are conflicting - require(areConflictingAttestations(attestation1, attestation2), "Attestations must be in conflict"); - - // Create the disputes - // The deposit is zero for conflicting attestations - bytes32 dID1 = _createQueryDisputeWithAttestation(fisherman, 0, attestation1, _attestationData1); - bytes32 dID2 = _createQueryDisputeWithAttestation(fisherman, 0, attestation2, _attestationData2); - - // Store the linked disputes to be resolved - disputes[dID1].relatedDisputeID = dID2; - disputes[dID2].relatedDisputeID = dID1; - - // Emit event that links the two created disputes - emit DisputeLinked(dID1, dID2); - - return (dID1, dID2); - } - - /** - * @notice Create a query dispute passing the parsed attestation. - * To be used in createQueryDispute() and createQueryDisputeConflict() - * to avoid calling parseAttestation() multiple times - * `_attestationData` is only passed to be emitted - * @param _fisherman Creator of dispute - * @param _deposit Amount of tokens staked as deposit - * @param _attestation Attestation struct parsed from bytes - * @param _attestationData Attestation bytes submitted by the fisherman - * @return DisputeID - */ - function _createQueryDisputeWithAttestation( - address _fisherman, - uint256 _deposit, - Attestation memory _attestation, - bytes memory _attestationData - ) private returns (bytes32) { - // Get the indexer that signed the attestation - address indexer = getAttestationIndexer(_attestation); - - // The indexer is disputable - require(staking().getIndexerStakedTokens(indexer) > 0, "Dispute indexer has no stake"); - - // Create a disputeID - bytes32 disputeID = keccak256( - abi.encodePacked( - _attestation.requestCID, - _attestation.responseCID, - _attestation.subgraphDeploymentID, - indexer, - _fisherman - ) - ); - - // Only one dispute for a (indexer, subgraphDeploymentID) at a time - require(!isDisputeCreated(disputeID), "Dispute already created"); - - // Store dispute - disputes[disputeID] = Dispute( - indexer, - _fisherman, - _deposit, - 0, // no related dispute, - DisputeType.QueryDispute, - IDisputeManager.DisputeStatus.Pending - ); - - emit QueryDisputeCreated( - disputeID, - indexer, - _fisherman, - _deposit, - _attestation.subgraphDeploymentID, - _attestationData - ); - - return disputeID; - } - - /** - * @dev Create an indexing dispute for the arbitrator to resolve. - * The disputes are created in reference to an allocationID - * This function is called by a challenger that will need to `_deposit` at - * least `minimumDeposit` GRT tokens. - * @inheritdoc IDisputeManager - */ - function createIndexingDispute(address _allocationID, uint256 _deposit) external override returns (bytes32) { - // Get funds from submitter - _pullSubmitterDeposit(_deposit); - - // Create a dispute - return _createIndexingDisputeWithAllocation(msg.sender, _deposit, _allocationID); - } - - /** - * @notice Create indexing dispute internal function. - * @param _fisherman The challenger creating the dispute - * @param _deposit Amount of tokens staked as deposit - * @param _allocationID Allocation disputed - * @return disputeID The ID of the created dispute - */ - function _createIndexingDisputeWithAllocation( - address _fisherman, - uint256 _deposit, - address _allocationID - ) private returns (bytes32) { - // Create a disputeID - bytes32 disputeID = keccak256(abi.encodePacked(_allocationID)); - - // Only one dispute for an allocationID at a time - require(!isDisputeCreated(disputeID), "Dispute already created"); - - // Allocation must exist - IStaking staking = staking(); - IStaking.Allocation memory alloc = staking.getAllocation(_allocationID); - require(alloc.indexer != address(0), "Dispute allocation must exist"); - - // The indexer must be disputable - require(staking.getIndexerStakedTokens(alloc.indexer) > 0, "Dispute indexer has no stake"); - - // Store dispute - disputes[disputeID] = Dispute( - alloc.indexer, - _fisherman, - _deposit, - 0, - DisputeType.IndexingDispute, - IDisputeManager.DisputeStatus.Pending - ); - - emit IndexingDisputeCreated(disputeID, alloc.indexer, _fisherman, _deposit, _allocationID); - - return disputeID; - } - - /** - * @dev This function will revert if the indexer is not slashable, whether because it does not have - * any stake available or the slashing percentage is configured to be zero. In those cases - * a dispute must be resolved using drawDispute or rejectDispute. - * @inheritdoc IDisputeManager - */ - function acceptDispute(bytes32 _disputeID) external override onlyArbitrator onlyPendingDispute(_disputeID) { - Dispute storage dispute = disputes[_disputeID]; - - // store the dispute status - dispute.status = IDisputeManager.DisputeStatus.Accepted; - - // Slash - (, uint256 tokensToReward) = _slashIndexer(dispute.indexer, dispute.fisherman, dispute.disputeType); - - // Give the fisherman their deposit back - TokenUtils.pushTokens(graphToken(), dispute.fisherman, dispute.deposit); - - if (_isDisputeInConflict(dispute)) { - rejectDispute(dispute.relatedDisputeID); - } - - emit DisputeAccepted(_disputeID, dispute.indexer, dispute.fisherman, dispute.deposit.add(tokensToReward)); - } - - /** - * @inheritdoc IDisputeManager - */ - function rejectDispute(bytes32 _disputeID) public override onlyArbitrator onlyPendingDispute(_disputeID) { - Dispute storage dispute = disputes[_disputeID]; - - // store dispute status - dispute.status = IDisputeManager.DisputeStatus.Rejected; - - // Handle conflicting dispute if any - require( - !_isDisputeInConflict(dispute), - "Dispute for conflicting attestation, must accept the related ID to reject" - ); - - // Burn the fisherman's deposit - TokenUtils.burnTokens(graphToken(), dispute.deposit); - - emit DisputeRejected(_disputeID, dispute.indexer, dispute.fisherman, dispute.deposit); - } - - /** - * @inheritdoc IDisputeManager - */ - function drawDispute(bytes32 _disputeID) external override onlyArbitrator onlyPendingDispute(_disputeID) { - Dispute storage dispute = disputes[_disputeID]; - - // Return deposit to the fisherman - TokenUtils.pushTokens(graphToken(), dispute.fisherman, dispute.deposit); - - // resolve related dispute if any - _drawDisputeInConflict(dispute); - - // store dispute status - dispute.status = IDisputeManager.DisputeStatus.Drawn; - - emit DisputeDrawn(_disputeID, dispute.indexer, dispute.fisherman, dispute.deposit); - } - - /** - * @notice Returns whether the dispute is for a conflicting attestation or not. - * @param _dispute Dispute - * @return True conflicting attestation dispute - */ - function _isDisputeInConflict(Dispute memory _dispute) private view returns (bool) { - bytes32 relatedID = _dispute.relatedDisputeID; - // this is so the check returns false when rejecting the related dispute. - return relatedID != 0 && disputes[relatedID].status == IDisputeManager.DisputeStatus.Pending; - } - - /** - * @notice Resolve the conflicting dispute if there is any for the one passed to this function. - * @param _dispute Dispute - * @return True if resolved - */ - function _drawDisputeInConflict(Dispute memory _dispute) private returns (bool) { - if (_isDisputeInConflict(_dispute)) { - bytes32 relatedDisputeID = _dispute.relatedDisputeID; - Dispute storage relatedDispute = disputes[relatedDisputeID]; - relatedDispute.status = IDisputeManager.DisputeStatus.Drawn; - return true; - } - return false; - } - - /** - * @notice Pull deposit from submitter account. - * @param _deposit Amount of tokens to deposit - */ - function _pullSubmitterDeposit(uint256 _deposit) private { - // Ensure that fisherman has staked at least the minimum amount - require(_deposit >= minimumDeposit, "Dispute deposit is under minimum required"); - - // Transfer tokens to deposit from fisherman to this contract - TokenUtils.pullTokens(graphToken(), msg.sender, _deposit); - } - - /** - * @notice Make the staking contract slash the indexer and reward the challenger. - * Give the challenger a reward equal to the fishermanRewardPercentage of slashed amount - * @param _indexer Address of the indexer - * @param _challenger Address of the challenger - * @param _disputeType Type of dispute - * @return slashAmount Dispute slash amount - * @return rewardsAmount Dispute rewards amount - */ - function _slashIndexer( - address _indexer, - address _challenger, - DisputeType _disputeType - ) private returns (uint256 slashAmount, uint256 rewardsAmount) { - IStaking staking = staking(); - - // Get slashable amount for indexer - uint256 slashableAmount = staking.getIndexerStakedTokens(_indexer); // slashable tokens - - // Get slash amount - slashAmount = _getSlashingPercentageForDisputeType(_disputeType).mul(slashableAmount).div(MAX_PPM); - require(slashAmount > 0, "Dispute has zero tokens to slash"); - - // Get rewards amount - rewardsAmount = uint256(fishermanRewardPercentage).mul(slashAmount).div(MAX_PPM); - - // Have staking contract slash the indexer and reward the fisherman - // Give the fisherman a reward equal to the fishermanRewardPercentage of slashed amount - staking.slash(_indexer, slashAmount, rewardsAmount, _challenger); - } - - /** - * @notice Return the slashing percentage for the dispute type. - * @param _disputeType Dispute type - * @return Slashing percentage to use for the dispute type - */ - function _getSlashingPercentageForDisputeType(DisputeType _disputeType) private view returns (uint256) { - if (_disputeType == DisputeType.QueryDispute) return uint256(qrySlashingPercentage); - if (_disputeType == DisputeType.IndexingDispute) return uint256(idxSlashingPercentage); - return 0; - } - - /** - * @notice Recover the signer address of the `_attestation`. - * @param _attestation The attestation struct - * @return Signer address - */ - function _recoverAttestationSigner(Attestation memory _attestation) private view returns (address) { - // Obtain the hash of the fully-encoded message, per EIP-712 encoding - Receipt memory receipt = Receipt( - _attestation.requestCID, - _attestation.responseCID, - _attestation.subgraphDeploymentID - ); - bytes32 messageHash = encodeHashReceipt(receipt); - - // Obtain the signer of the fully-encoded EIP-712 message hash - // NOTE: The signer of the attestation is the indexer that served the request - return ECDSA.recover(messageHash, abi.encodePacked(_attestation.r, _attestation.s, _attestation.v)); - } - - /** - * @notice Get the running network chain ID - * @return The chain ID - */ - function _getChainID() private pure returns (uint256) { - uint256 id; - // solhint-disable-next-line no-inline-assembly - assembly { - id := chainid() - } - return id; - } - - /** - * @notice Parse the bytes attestation into a struct from `_data`. - * @param _data The bytes data to parse into an attestation - * @return Attestation struct - */ - function _parseAttestation(bytes memory _data) private pure returns (Attestation memory) { - // Check attestation data length - require(_data.length == ATTESTATION_SIZE_BYTES, "Attestation must be 161 bytes long"); - - // Decode receipt - (bytes32 requestCID, bytes32 responseCID, bytes32 subgraphDeploymentID) = abi.decode( - _data, - (bytes32, bytes32, bytes32) - ); - - // Decode signature - // Signature is expected to be in the order defined in the Attestation struct - bytes32 r = _toBytes32(_data, SIG_R_OFFSET); - bytes32 s = _toBytes32(_data, SIG_S_OFFSET); - uint8 v = _toUint8(_data, SIG_V_OFFSET); - - return Attestation(requestCID, responseCID, subgraphDeploymentID, r, s, v); - } - - /** - * @notice Parse a uint8 from `_bytes` starting at offset `_start`. - * @param _bytes The bytes array to parse from - * @param _start The starting offset in the bytes array - * @return uint8 value - */ - function _toUint8(bytes memory _bytes, uint256 _start) private pure returns (uint8) { - require(_bytes.length >= (_start + UINT8_BYTE_LENGTH), "Bytes: out of bounds"); - uint8 tempUint; - - // solhint-disable-next-line no-inline-assembly - assembly { - tempUint := mload(add(add(_bytes, 0x1), _start)) - } - - return tempUint; - } - - /** - * @notice Parse a bytes32 from `_bytes` starting at offset `_start`. - * @param _bytes The bytes array to parse from - * @param _start The starting offset in the bytes array - * @return bytes32 value - */ - function _toBytes32(bytes memory _bytes, uint256 _start) private pure returns (bytes32) { - require(_bytes.length >= (_start + BYTES32_BYTE_LENGTH), "Bytes: out of bounds"); - bytes32 tempBytes32; - - // solhint-disable-next-line no-inline-assembly - assembly { - tempBytes32 := mload(add(add(_bytes, 0x20), _start)) - } - - return tempBytes32; - } -} diff --git a/packages/contracts/contracts/disputes/DisputeManagerStorage.sol b/packages/contracts/contracts/disputes/DisputeManagerStorage.sol deleted file mode 100644 index f2ad2b7c3..000000000 --- a/packages/contracts/contracts/disputes/DisputeManagerStorage.sol +++ /dev/null @@ -1,44 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable named-parameters-mapping - -pragma solidity ^0.7.6; - -import { Managed } from "../governance/Managed.sol"; - -import { IDisputeManager } from "@graphprotocol/interfaces/contracts/contracts/disputes/IDisputeManager.sol"; - -/** - * @title Dispute Manager Storage V1 - * @author Edge & Node - * @notice Storage contract for the Dispute Manager - */ -contract DisputeManagerV1Storage is Managed { - // -- State -- - - /// @dev Domain separator for EIP-712 signature verification - bytes32 internal DOMAIN_SEPARATOR; // solhint-disable-line var-name-mixedcase - - /// @notice The arbitrator is solely in control of arbitrating disputes - address public arbitrator; - - /// @notice Minimum deposit required to create a Dispute - uint256 public minimumDeposit; - - // -- Slot 0xf - /// @notice Percentage of indexer slashed funds to assign as a reward to fisherman in successful dispute - /// Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) - uint32 public fishermanRewardPercentage; - - /// @notice Percentage of indexer stake to slash on disputes - /// Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) - uint32 public qrySlashingPercentage; - /// @notice Percentage of indexer stake to slash on disputes - uint32 public idxSlashingPercentage; - - // -- Slot 0x10 - /// @notice Disputes created : disputeID => Dispute - /// @dev disputeID - check creation functions to see how disputeID is built - mapping(bytes32 => IDisputeManager.Dispute) public disputes; -} diff --git a/packages/contracts/contracts/l2/staking/L2Staking.sol b/packages/contracts/contracts/l2/staking/L2Staking.sol deleted file mode 100644 index 305747801..000000000 --- a/packages/contracts/contracts/l2/staking/L2Staking.sol +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable gas-indexed-events - -import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; -import { Staking } from "../../staking/Staking.sol"; -import { IL2StakingBase } from "@graphprotocol/interfaces/contracts/contracts/l2/staking/IL2StakingBase.sol"; -import { Stakes } from "../../staking/libs/Stakes.sol"; -import { IStakes } from "@graphprotocol/interfaces/contracts/contracts/staking/libs/IStakes.sol"; -import { IL2StakingTypes } from "@graphprotocol/interfaces/contracts/contracts/l2/staking/IL2StakingTypes.sol"; - -// solhint-disable-next-line no-unused-import -import { ICallhookReceiver } from "@graphprotocol/interfaces/contracts/contracts/gateway/ICallhookReceiver.sol"; // Used by @inheritdoc - -/** - * @title L2Staking contract - * @author Edge & Node - * @notice This contract is the L2 variant of the Staking contract. It adds a function - * to receive an indexer's stake or delegation from L1. Note that this contract inherits Staking, - * which uses a StakingExtension contract to implement the full IStaking interface through delegatecalls. - */ -contract L2Staking is Staking, IL2StakingBase { - using SafeMath for uint256; - using Stakes for IStakes.Indexer; - - /// @dev Minimum amount of tokens that can be delegated - uint256 private constant MINIMUM_DELEGATION = 1e18; - - /** - * @notice Emitted when `delegator` delegated `tokens` to the `indexer`, the delegator - * gets `shares` for the delegation pool proportionally to the tokens staked. - * This is copied from IStakingExtension, but we can't inherit from it because we - * don't implement the full interface here. - * @param indexer Address of the indexer receiving the delegation - * @param delegator Address of the delegator - * @param tokens Amount of tokens delegated - * @param shares Amount of shares issued to the delegator - */ - event StakeDelegated(address indexed indexer, address indexed delegator, uint256 tokens, uint256 shares); - - /** - * @dev Checks that the sender is the L2GraphTokenGateway as configured on the Controller. - */ - modifier onlyL2Gateway() { - require(msg.sender == address(graphTokenGateway()), "ONLY_GATEWAY"); - _; - } - - /** - * @notice Receive ETH into the L2Staking contract: this will always revert - * @dev This function is only here to prevent ETH from being sent to the contract - */ - receive() external payable { - revert("RECEIVE_ETH_NOT_ALLOWED"); - } - - /** - * @inheritdoc ICallhookReceiver - * @dev The encoded _data can contain information about an indexer's stake - * or a delegator's delegation. - * See L1MessageCodes in IL2Staking for the supported messages. - * @param _from Token sender in L1 - * @param _amount Amount of tokens that were transferred - * @param _data ABI-encoded callhook data which must include a uint8 code and either a ReceiveIndexerStakeData or ReceiveDelegationData struct. - */ - function onTokenTransfer( - address _from, - uint256 _amount, - bytes calldata _data - ) external override notPartialPaused onlyL2Gateway { - require(_from == counterpartStakingAddress, "ONLY_L1_STAKING_THROUGH_BRIDGE"); - (uint8 code, bytes memory functionData) = abi.decode(_data, (uint8, bytes)); - - if (code == uint8(IL2StakingTypes.L1MessageCodes.RECEIVE_INDEXER_STAKE_CODE)) { - IL2StakingTypes.ReceiveIndexerStakeData memory indexerData = abi.decode( - functionData, - (IL2StakingTypes.ReceiveIndexerStakeData) - ); - _receiveIndexerStake(_amount, indexerData); - } else if (code == uint8(IL2StakingTypes.L1MessageCodes.RECEIVE_DELEGATION_CODE)) { - IL2StakingTypes.ReceiveDelegationData memory delegationData = abi.decode( - functionData, - (IL2StakingTypes.ReceiveDelegationData) - ); - _receiveDelegation(_amount, delegationData); - } else { - revert("INVALID_CODE"); - } - } - - /** - * @notice Receive an Indexer's stake from L1. - * The specified amount is added to the indexer's stake; the indexer's - * address is specified in the _indexerData struct. - * @param _amount Amount of tokens that were transferred - * @param _indexerData struct containing the indexer's address - */ - function _receiveIndexerStake( - uint256 _amount, - IL2StakingTypes.ReceiveIndexerStakeData memory _indexerData - ) internal { - address _indexer = _indexerData.indexer; - // Deposit tokens into the indexer stake - __stakes[_indexer].deposit(_amount); - - // Initialize the delegation pool the first time - if (__delegationPools[_indexer].updatedAtBlock == 0) { - _setDelegationParameters(_indexer, MAX_PPM, MAX_PPM); - } - - emit StakeDeposited(_indexer, _amount); - } - - /** - * @notice Receive a Delegator's delegation from L1. - * The specified amount is added to the delegator's delegation; the delegator's - * address and the indexer's address are specified in the _delegationData struct. - * Note that no delegation tax is applied here. - * @param _amount Amount of tokens that were transferred - * @param _delegationData struct containing the delegator's address and the indexer's address - */ - function _receiveDelegation( - uint256 _amount, - IL2StakingTypes.ReceiveDelegationData memory _delegationData - ) internal { - // Get the delegation pool of the indexer - DelegationPool storage pool = __delegationPools[_delegationData.indexer]; - Delegation storage delegation = pool.delegators[_delegationData.delegator]; - - // Calculate shares to issue (without applying any delegation tax) - uint256 shares = (pool.tokens == 0) ? _amount : _amount.mul(pool.shares).div(pool.tokens); - - if (shares == 0 || _amount < MINIMUM_DELEGATION) { - // If no shares would be issued (probably a rounding issue or attack), - // or if the amount is under the minimum delegation (which could be part of a rounding attack), - // return the tokens to the delegator - graphToken().transfer(_delegationData.delegator, _amount); - emit TransferredDelegationReturnedToDelegator(_delegationData.indexer, _delegationData.delegator, _amount); - } else { - // Update the delegation pool - pool.tokens = pool.tokens.add(_amount); - pool.shares = pool.shares.add(shares); - - // Update the individual delegation - delegation.shares = delegation.shares.add(shares); - - emit StakeDelegated(_delegationData.indexer, _delegationData.delegator, _amount, shares); - } - } -} diff --git a/packages/contracts/contracts/payments/AllocationExchange.sol b/packages/contracts/contracts/payments/AllocationExchange.sol deleted file mode 100644 index 288bdda32..000000000 --- a/packages/contracts/contracts/payments/AllocationExchange.sol +++ /dev/null @@ -1,194 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable gas-calldata-parameters, gas-increment-by-one, gas-indexed-events, gas-small-strings -// solhint-disable named-parameters-mapping - -import { ECDSA } from "@openzeppelin/contracts/cryptography/ECDSA.sol"; -import { Address } from "@openzeppelin/contracts/utils/Address.sol"; -import { Governed } from "../governance/Governed.sol"; -import { IStaking } from "@graphprotocol/interfaces/contracts/contracts/staking/IStaking.sol"; -import { IGraphToken } from "@graphprotocol/interfaces/contracts/contracts/token/IGraphToken.sol"; - -/** - * @title Allocation Exchange - * @author Edge & Node - * @notice This contract holds tokens that anyone with a voucher signed by the - * authority can redeem. The contract validates if the voucher presented is valid - * and then sends tokens to the Staking contract by calling the collect() function - * passing the voucher allocationID. The contract enforces that only one voucher for - * an allocationID can be redeemed. - * Only governance can change the authority. - */ -contract AllocationExchange is Governed { - /** - * @dev An allocation voucher represents a signed message that allows - * redeeming an amount of funds from this contract and collect - * them as part of an allocation - * @param allocationID Address of the allocation - * @param amount Amount of tokens to redeem - * @param signature Signature from the authority (65 bytes) - */ - struct AllocationVoucher { - address allocationID; - uint256 amount; - bytes signature; // 65 bytes - } - - // -- Constants -- - - /// @dev Maximum uint256 value used for unlimited token approvals - uint256 private constant MAX_UINT256 = 2 ** 256 - 1; - /// @dev Expected length of ECDSA signatures - uint256 private constant SIGNATURE_LENGTH = 65; - - // -- State -- - - /// @dev Reference to the Staking contract - IStaking private immutable STAKING; - /// @dev Reference to the Graph Token contract - IGraphToken private immutable GRAPH_TOKEN; - /// @notice Mapping of authorized accounts that can redeem allocations - mapping(address => bool) public authority; - /// @notice Mapping of allocations that have been redeemed - mapping(address => bool) public allocationsRedeemed; - - // -- Events - - /** - * @notice Emitted when an authority is set or unset - * @param account Address of the authority - * @param authorized Whether the authority is authorized - */ - event AuthoritySet(address indexed account, bool authorized); - - /** - * @notice Emitted when an allocation voucher is redeemed - * @param allocationID Address of the allocation - * @param amount Amount of tokens redeemed - */ - event AllocationRedeemed(address indexed allocationID, uint256 amount); - - /** - * @notice Emitted when tokens are withdrawn from the contract - * @param to Address that received the tokens - * @param amount Amount of tokens withdrawn - */ - event TokensWithdrawn(address indexed to, uint256 amount); - - // -- Functions - - /** - * @notice Contract constructor. - * @param _graphToken Address of the GRT token - * @param _staking Address of the protocol Staking contract - * @param _governor Account capable of withdrawing funds and setting the authority - * @param _authority Account that can sign the vouchers that this contract will redeem - */ - constructor(IGraphToken _graphToken, IStaking _staking, address _governor, address _authority) { - require(_governor != address(0), "Exchange: governor must be set"); - Governed._initialize(_governor); - - GRAPH_TOKEN = _graphToken; - STAKING = _staking; - _setAuthority(_authority, true); - } - - /** - * @notice Approve the staking contract to pull any amount of tokens from this contract. - * @dev Increased gas efficiency instead of approving on each voucher redeem - */ - function approveAll() external { - GRAPH_TOKEN.approve(address(STAKING), MAX_UINT256); - } - - /** - * @notice Withdraw tokens held in the contract. - * @dev Only the governor can withdraw - * @param _to Destination to send the tokens - * @param _amount Amount of tokens to withdraw - */ - function withdraw(address _to, uint256 _amount) external onlyGovernor { - require(_to != address(0), "Exchange: empty destination"); - require(_amount != 0, "Exchange: empty amount"); - require(GRAPH_TOKEN.transfer(_to, _amount), "Exchange: cannot transfer"); - emit TokensWithdrawn(_to, _amount); - } - - /** - * @notice Set the authority allowed to sign vouchers. - * @dev Only the governor can set the authority - * @param _authority Address of the signing authority - * @param _authorized True if the authority is authorized to sign vouchers, false to unset - */ - function setAuthority(address _authority, bool _authorized) external onlyGovernor { - _setAuthority(_authority, _authorized); - } - - /** - * @notice Set the authority allowed to sign vouchers. - * @param _authority Address of the signing authority - * @param _authorized True if the authority is authorized to sign vouchers, false to unset - */ - function _setAuthority(address _authority, bool _authorized) private { - require(_authority != address(0), "Exchange: empty authority"); - // This will help catch some operational errors but not all. - // The validation will fail under the following conditions: - // - a contract in construction - // - an address where a contract will be created - // - an address where a contract lived, but was destroyed - require(!Address.isContract(_authority), "Exchange: authority must be EOA"); - authority[_authority] = _authorized; - emit AuthoritySet(_authority, _authorized); - } - - /** - * @notice Redeem a voucher signed by the authority. No voucher double spending is allowed. - * @dev The voucher must be signed using an Ethereum signed message - * @param _voucher Voucher data - */ - function redeem(AllocationVoucher memory _voucher) external { - _redeem(_voucher); - } - - /** - * @notice Redeem multiple vouchers. - * @dev Each voucher must be signed using an Ethereum signed message - * @param _vouchers An array of vouchers - */ - function redeemMany(AllocationVoucher[] memory _vouchers) external { - for (uint256 i = 0; i < _vouchers.length; i++) { - _redeem(_vouchers[i]); - } - } - - /** - * @notice Redeem a voucher signed by the authority. No voucher double spending is allowed. - * @dev The voucher must be signed using an Ethereum signed message - * @param _voucher Voucher data - */ - function _redeem(AllocationVoucher memory _voucher) private { - require(_voucher.amount > 0, "Exchange: zero tokens voucher"); - require(_voucher.signature.length == SIGNATURE_LENGTH, "Exchange: invalid signature"); - - // Already redeemed check - require(!allocationsRedeemed[_voucher.allocationID], "Exchange: allocation already redeemed"); - - // Signature check - bytes32 messageHash = keccak256(abi.encodePacked(_voucher.allocationID, _voucher.amount)); - address voucherSigner = ECDSA.recover(messageHash, _voucher.signature); - require(authority[voucherSigner], "Exchange: invalid signer"); - - // Mark allocation as collected - allocationsRedeemed[_voucher.allocationID] = true; - - // Make the staking contract collect funds from this contract - // The Staking contract will validate if the allocation is valid - STAKING.collect(_voucher.amount, _voucher.allocationID); - - emit AllocationRedeemed(_voucher.allocationID, _voucher.amount); - } -} diff --git a/packages/contracts/contracts/rewards/SubgraphAvailabilityManager.sol b/packages/contracts/contracts/rewards/SubgraphAvailabilityManager.sol deleted file mode 100644 index d24577b42..000000000 --- a/packages/contracts/contracts/rewards/SubgraphAvailabilityManager.sol +++ /dev/null @@ -1,247 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable gas-increment-by-one, gas-indexed-events, gas-small-strings, gas-strict-inequalities -// solhint-disable named-parameters-mapping - -import { Governed } from "../governance/Governed.sol"; -import { IRewardsManager } from "@graphprotocol/interfaces/contracts/contracts/rewards/IRewardsManager.sol"; - -/** - * @title Subgraph Availability Manager - * @author Edge & Node - * @notice Manages the availability of subgraphs by allowing oracles to vote on whether - * a subgraph should be denied rewards or not. When enough oracles have voted to deny or - * allow rewards for a subgraph, it calls the RewardsManager Contract to set the correct - * state. The oracles and the execution threshold are set at deployment time. - * Only governance can update the oracles and voteTimeLimit. - * Governor can transfer ownership to a new governor. - */ -contract SubgraphAvailabilityManager is Governed { - // -- Immutable -- - - /// @notice Number of oracles - uint256 public constant NUM_ORACLES = 5; - - /// @notice Number of votes required to execute a deny or allow call to the RewardsManager - uint256 public immutable executionThreshold; // solhint-disable-line immutable-vars-naming - - /// @dev Address of the RewardsManager contract - // solhint-disable-next-line immutable-vars-naming - IRewardsManager private immutable rewardsManager; - - // -- State -- - - /// @notice Nonce for generating votes on subgraph deployment IDs - /// @dev Increased whenever oracles or voteTimeLimit change, to invalidate old votes - uint256 public currentNonce; - - /// @notice Time limit for a vote to be valid - uint256 public voteTimeLimit; - - /// @notice Array of oracle addresses - address[NUM_ORACLES] public oracles; - - /// @notice Mapping of current nonce to subgraph deployment ID to an array of timestamps of last deny vote - /// @dev currentNonce => subgraphDeploymentId => timestamp[oracleIndex] - mapping(uint256 => mapping(bytes32 => uint256[NUM_ORACLES])) public lastDenyVote; - - /// @notice Mapping of current nonce to subgraph deployment ID to an array of timestamp of last allow vote - /// @dev currentNonce => subgraphDeploymentId => timestamp[oracleIndex] - mapping(uint256 => mapping(bytes32 => uint256[NUM_ORACLES])) public lastAllowVote; - - // -- Events -- - - /** - * @notice Emitted when an oracle is set - * @param index Index of the oracle - * @param oracle Address of the oracle - */ - event OracleSet(uint256 indexed index, address indexed oracle); - - /** - * @notice Emitted when the vote time limit is set - * @param voteTimeLimit Vote time limit in seconds - */ - event VoteTimeLimitSet(uint256 voteTimeLimit); - - /** - * @notice Emitted when an oracle votes to deny or allow a subgraph - * @param subgraphDeploymentID Subgraph deployment ID - * @param deny True to deny, false to allow - * @param oracleIndex Index of the oracle voting - * @param timestamp Timestamp of the vote - */ - event OracleVote(bytes32 indexed subgraphDeploymentID, bool deny, uint256 indexed oracleIndex, uint256 timestamp); - - // -- Modifiers -- - - /** - * @dev Modifier to restrict access to authorized oracles only - * @param _oracleIndex Index of the oracle in the oracles array - */ - modifier onlyOracle(uint256 _oracleIndex) { - require(_oracleIndex < NUM_ORACLES, "SAM: index out of bounds"); - require(msg.sender == oracles[_oracleIndex], "SAM: caller must be oracle"); - _; - } - - // -- Constructor -- - - /** - * @notice Contract constructor - * @param _governor Account that can set or remove oracles and set the vote time limit - * @param _rewardsManager Address of the RewardsManager contract - * @param _executionThreshold Number of votes required to execute a deny or allow call to the RewardsManager - * @param _voteTimeLimit Vote time limit in seconds - * @param _oracles Array of oracle addresses, must be NUM_ORACLES in length. - */ - constructor( - address _governor, - address _rewardsManager, - uint256 _executionThreshold, - uint256 _voteTimeLimit, - address[NUM_ORACLES] memory _oracles - ) { - require(_governor != address(0), "SAM: governor must be set"); - require(_rewardsManager != address(0), "SAM: rewardsManager must be set"); - require(_executionThreshold >= (NUM_ORACLES / 2) + 1, "SAM: executionThreshold too low"); - require(_executionThreshold <= NUM_ORACLES, "SAM: executionThreshold too high"); - - // Oracles should not be address zero - for (uint256 i; i < _oracles.length; i++) { - address oracle = _oracles[i]; - require(oracle != address(0), "SAM: oracle cannot be address zero"); - oracles[i] = oracle; - emit OracleSet(i, oracle); - } - - Governed._initialize(_governor); - rewardsManager = IRewardsManager(_rewardsManager); - - executionThreshold = _executionThreshold; - voteTimeLimit = _voteTimeLimit; - } - - // -- Functions -- - - /** - * @notice Set the vote time limit. Refreshes all existing votes by incrementing the current nonce. - * @param _voteTimeLimit Vote time limit in seconds - */ - function setVoteTimeLimit(uint256 _voteTimeLimit) external onlyGovernor { - voteTimeLimit = _voteTimeLimit; - currentNonce++; - emit VoteTimeLimitSet(_voteTimeLimit); - } - - /** - * @notice Set oracle address with index. Refreshes all existing votes by incrementing the current nonce. - * @param _index Index of the oracle - * @param _oracle Address of the oracle - */ - function setOracle(uint256 _index, address _oracle) external onlyGovernor { - require(_index < NUM_ORACLES, "SAM: index out of bounds"); - require(_oracle != address(0), "SAM: oracle cannot be address zero"); - - oracles[_index] = _oracle; - // Increment the current nonce to refresh all existing votes for subgraph deployment IDs - currentNonce++; - - emit OracleSet(_index, _oracle); - } - - /** - * @notice Vote deny or allow for a subgraph. - * NOTE: Can only be called by an oracle. - * @param _subgraphDeploymentID Subgraph deployment ID - * @param _deny True to deny, false to allow - * @param _oracleIndex Index of the oracle voting - */ - function vote(bytes32 _subgraphDeploymentID, bool _deny, uint256 _oracleIndex) external onlyOracle(_oracleIndex) { - _vote(_subgraphDeploymentID, _deny, _oracleIndex); - } - - /** - * @notice Vote deny or allow for many subgraphs. - * NOTE: Can only be called by an oracle. - * @param _subgraphDeploymentID Array of subgraph deployment IDs - * @param _deny Array of booleans, true to deny, false to allow - * @param _oracleIndex Index of the oracle voting - */ - function voteMany( - bytes32[] calldata _subgraphDeploymentID, - bool[] calldata _deny, - uint256 _oracleIndex - ) external onlyOracle(_oracleIndex) { - require(_subgraphDeploymentID.length == _deny.length, "!length"); - for (uint256 i; i < _subgraphDeploymentID.length; i++) { - _vote(_subgraphDeploymentID[i], _deny[i], _oracleIndex); - } - } - - /** - * @notice Vote deny or allow for a subgraph. - * When oracles cast their votes we store the timestamp of the vote. - * Check if the execution threshold has been reached for a subgraph. - * If execution threshold is reached we call the RewardsManager to set the correct state. - * @param _subgraphDeploymentID Subgraph deployment ID - * @param _deny True to deny, false to allow - * @param _oracleIndex Index of the oracle voting - */ - function _vote(bytes32 _subgraphDeploymentID, bool _deny, uint256 _oracleIndex) private { - uint256 timestamp = block.timestamp; - - if (_deny) { - lastDenyVote[currentNonce][_subgraphDeploymentID][_oracleIndex] = timestamp; - // clear opposite vote for a subgraph deployment if it exists - lastAllowVote[currentNonce][_subgraphDeploymentID][_oracleIndex] = 0; - } else { - lastAllowVote[currentNonce][_subgraphDeploymentID][_oracleIndex] = timestamp; - // clear opposite vote for a subgraph deployment if it exists - lastDenyVote[currentNonce][_subgraphDeploymentID][_oracleIndex] = 0; - } - - emit OracleVote(_subgraphDeploymentID, _deny, _oracleIndex, timestamp); - - // check if execution threshold is reached, if it is call the RewardsManager - if (checkVotes(_subgraphDeploymentID, _deny)) { - rewardsManager.setDenied(_subgraphDeploymentID, _deny); - } - } - - /** - * @notice Check if the execution threshold has been reached for a subgraph. - * For a vote to be valid it needs to be within the vote time limit. - * @param _subgraphDeploymentID Subgraph deployment ID - * @param _deny True to deny, false to allow - * @return True if execution threshold is reached - */ - function checkVotes(bytes32 _subgraphDeploymentID, bool _deny) public view returns (bool) { - uint256 votes; - - // timeframe for a vote to be valid - uint256 voteTimeValidity = block.timestamp - voteTimeLimit; - - // corresponding votes based on _deny for a subgraph deployment - uint256[NUM_ORACLES] storage lastVoteForSubgraph = _deny - ? lastDenyVote[currentNonce][_subgraphDeploymentID] - : lastAllowVote[currentNonce][_subgraphDeploymentID]; - - for (uint256 i; i < NUM_ORACLES; i++) { - // check if vote is within the vote time limit - if (lastVoteForSubgraph[i] > voteTimeValidity) { - votes++; - } - - // check if execution threshold is reached - if (votes == executionThreshold) { - return true; - } - } - - return false; - } -} diff --git a/packages/contracts/contracts/staking/L1Staking.sol b/packages/contracts/contracts/staking/L1Staking.sol deleted file mode 100644 index b2a00c57e..000000000 --- a/packages/contracts/contracts/staking/L1Staking.sol +++ /dev/null @@ -1,326 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable function-max-lines, gas-strict-inequalities - -import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; - -import { ITokenGateway } from "@graphprotocol/interfaces/contracts/contracts/arbitrum/ITokenGateway.sol"; -import { Staking } from "./Staking.sol"; -import { Stakes } from "./libs/Stakes.sol"; -import { IStakes } from "@graphprotocol/interfaces/contracts/contracts/staking/libs/IStakes.sol"; -import { IStakingData } from "@graphprotocol/interfaces/contracts/contracts/staking/IStakingData.sol"; -import { L1StakingV1Storage } from "./L1StakingStorage.sol"; -import { IGraphToken } from "@graphprotocol/interfaces/contracts/contracts/token/IGraphToken.sol"; -import { IL1StakingBase } from "@graphprotocol/interfaces/contracts/contracts/staking/IL1StakingBase.sol"; -import { MathUtils } from "./libs/MathUtils.sol"; -import { IL1GraphTokenLockTransferTool } from "@graphprotocol/interfaces/contracts/contracts/staking/IL1GraphTokenLockTransferTool.sol"; -import { IL2StakingTypes } from "@graphprotocol/interfaces/contracts/contracts/l2/staking/IL2StakingTypes.sol"; - -/** - * @title L1Staking contract - * @author Edge & Node - * @notice This contract is the L1 variant of the Staking contract. It adds functions - * to send an indexer's stake to L2, and to send delegation to L2 as well. - */ -contract L1Staking is Staking, L1StakingV1Storage, IL1StakingBase { - using Stakes for IStakes.Indexer; - using SafeMath for uint256; - - /** - * @notice Receive ETH into the Staking contract - * @dev Only the L1GraphTokenLockTransferTool can send ETH, as part of the - * transfer of stake/delegation for vesting lock wallets. - */ - receive() external payable { - require(msg.sender == address(l1GraphTokenLockTransferTool), "Only transfer tool can send ETH"); - } - - /** - * @inheritdoc IL1StakingBase - */ - function setL1GraphTokenLockTransferTool( - IL1GraphTokenLockTransferTool _l1GraphTokenLockTransferTool - ) external override onlyGovernor { - l1GraphTokenLockTransferTool = _l1GraphTokenLockTransferTool; - emit L1GraphTokenLockTransferToolSet(address(_l1GraphTokenLockTransferTool)); - } - - /** - * @inheritdoc IL1StakingBase - */ - function transferStakeToL2( - address _l2Beneficiary, - uint256 _amount, - uint256 _maxGas, - uint256 _gasPriceBid, - uint256 _maxSubmissionCost - ) external payable override notPartialPaused { - require(msg.value == _maxSubmissionCost.add(_gasPriceBid.mul(_maxGas)), "INVALID_ETH_AMOUNT"); - _transferStakeToL2(msg.sender, _l2Beneficiary, _amount, _maxGas, _gasPriceBid, _maxSubmissionCost, msg.value); - } - - /** - * @inheritdoc IL1StakingBase - */ - function transferLockedStakeToL2( - uint256 _amount, - uint256 _maxGas, - uint256 _gasPriceBid, - uint256 _maxSubmissionCost - ) external override notPartialPaused { - address l2Beneficiary = l1GraphTokenLockTransferTool.l2WalletAddress(msg.sender); - require(l2Beneficiary != address(0), "LOCK NOT TRANSFERRED"); - uint256 balance = address(this).balance; - uint256 ethAmount = _maxSubmissionCost.add(_maxGas.mul(_gasPriceBid)); - l1GraphTokenLockTransferTool.pullETH(msg.sender, ethAmount); - require(address(this).balance == balance.add(ethAmount), "ETH TRANSFER FAILED"); - _transferStakeToL2(msg.sender, l2Beneficiary, _amount, _maxGas, _gasPriceBid, _maxSubmissionCost, ethAmount); - } - - /** - * @inheritdoc IL1StakingBase - */ - function transferDelegationToL2( - address _indexer, - address _l2Beneficiary, - uint256 _maxGas, - uint256 _gasPriceBid, - uint256 _maxSubmissionCost - ) external payable override notPartialPaused { - require(msg.value == _maxSubmissionCost.add(_gasPriceBid.mul(_maxGas)), "INVALID_ETH_AMOUNT"); - _transferDelegationToL2( - msg.sender, - _indexer, - _l2Beneficiary, - _maxGas, - _gasPriceBid, - _maxSubmissionCost, - msg.value - ); - } - - /** - * @inheritdoc IL1StakingBase - */ - function transferLockedDelegationToL2( - address _indexer, - uint256 _maxGas, - uint256 _gasPriceBid, - uint256 _maxSubmissionCost - ) external override notPartialPaused { - address l2Beneficiary = l1GraphTokenLockTransferTool.l2WalletAddress(msg.sender); - require(l2Beneficiary != address(0), "LOCK NOT TRANSFERRED"); - uint256 balance = address(this).balance; - uint256 ethAmount = _maxSubmissionCost.add(_maxGas.mul(_gasPriceBid)); - l1GraphTokenLockTransferTool.pullETH(msg.sender, ethAmount); - require(address(this).balance == balance.add(ethAmount), "ETH TRANSFER FAILED"); - _transferDelegationToL2( - msg.sender, - _indexer, - l2Beneficiary, - _maxGas, - _gasPriceBid, - _maxSubmissionCost, - ethAmount - ); - } - - /** - * @inheritdoc IL1StakingBase - */ - function unlockDelegationToTransferredIndexer(address _indexer) external override notPartialPaused { - require( - indexerTransferredToL2[_indexer] != address(0) && __stakes[_indexer].tokensStaked == 0, - "indexer not transferred" - ); - - Delegation storage delegation = __delegationPools[_indexer].delegators[msg.sender]; - require(delegation.tokensLocked != 0, "! locked"); - - // Unlock the delegation - delegation.tokensLockedUntil = epochManager().currentEpoch(); - - // After this, the delegator should be able to withdraw in the current block - emit StakeDelegatedUnlockedDueToL2Transfer(_indexer, msg.sender); - } - - /** - * @notice Implements sending an indexer's stake to L2. - * This function can only be called by the indexer (not an operator). - * It will validate that the remaining stake is sufficient to cover all the allocated - * stake, so the indexer might have to close some allocations before transferring. - * It will also check that the indexer's stake is not locked for withdrawal. - * Since the indexer address might be an L1-only contract, the function takes a beneficiary - * address that will be the indexer's address in L2. - * @param _indexer Address of the indexer transferring stake - * @param _l2Beneficiary Address of the indexer in L2. If the indexer has previously transferred stake, this must match the previously-used value. - * @param _amount Amount of stake GRT to transfer to L2 - * @param _maxGas Max gas to use for the L2 retryable ticket - * @param _gasPriceBid Gas price bid for the L2 retryable ticket - * @param _maxSubmissionCost Max submission cost for the L2 retryable ticket - * @param _ethAmount Amount of ETH to send with the retryable ticket - */ - function _transferStakeToL2( - address _indexer, - address _l2Beneficiary, - uint256 _amount, - uint256 _maxGas, - uint256 _gasPriceBid, - uint256 _maxSubmissionCost, - uint256 _ethAmount - ) internal { - IStakes.Indexer storage indexerStake = __stakes[_indexer]; - require(indexerStake.tokensStaked != 0, "tokensStaked == 0"); - // Indexers shouldn't be trying to withdraw tokens before transferring to L2. - // Allowing this would complicate our accounting so we require that they have no - // tokens locked for withdrawal. - require(indexerStake.tokensLocked == 0, "tokensLocked != 0"); - - require(_l2Beneficiary != address(0), "l2Beneficiary == 0"); - if (indexerTransferredToL2[_indexer] != address(0)) { - require(indexerTransferredToL2[_indexer] == _l2Beneficiary, "l2Beneficiary != previous"); - } else { - indexerTransferredToL2[_indexer] = _l2Beneficiary; - require(_amount >= __minimumIndexerStake, "!minimumIndexerStake sent"); - } - // Ensure minimum stake - indexerStake.tokensStaked = indexerStake.tokensStaked.sub(_amount); - require( - indexerStake.tokensStaked == 0 || indexerStake.tokensStaked >= __minimumIndexerStake, - "!minimumIndexerStake remaining" - ); - - IStakingData.DelegationPool storage delegationPool = __delegationPools[_indexer]; - - if (indexerStake.tokensStaked == 0) { - // require that no allocations are open - require(indexerStake.tokensAllocated == 0, "allocated"); - } else { - // require that the indexer has enough stake to cover all allocations - uint256 tokensDelegatedCap = indexerStake.tokensStaked.mul(uint256(__delegationRatio)); - uint256 tokensDelegatedCapacity = MathUtils.min(delegationPool.tokens, tokensDelegatedCap); - require( - indexerStake.tokensUsed() <= indexerStake.tokensStaked.add(tokensDelegatedCapacity), - "! allocation capacity" - ); - } - - IL2StakingTypes.ReceiveIndexerStakeData memory functionData; - functionData.indexer = _l2Beneficiary; - - bytes memory extraData = abi.encode( - uint8(IL2StakingTypes.L1MessageCodes.RECEIVE_INDEXER_STAKE_CODE), - abi.encode(functionData) - ); - - _sendTokensAndMessageToL2Staking(_amount, _maxGas, _gasPriceBid, _maxSubmissionCost, _ethAmount, extraData); - - emit IndexerStakeTransferredToL2(_indexer, _l2Beneficiary, _amount); - } - - /** - * @notice Implements sending a delegator's delegated tokens to L2. - * This function can only be called by the delegator. - * This function will validate that the indexer has transferred their stake using transferStakeToL2, - * and that the delegation is not locked for undelegation. - * Since the delegator's address might be an L1-only contract, the function takes a beneficiary - * address that will be the delegator's address in L2. - * @param _delegator Address of the delegator transferring delegation - * @param _indexer Address of the indexer (in L1, before transferring to L2) - * @param _l2Beneficiary Address of the delegator in L2 - * @param _maxGas Max gas to use for the L2 retryable ticket - * @param _gasPriceBid Gas price bid for the L2 retryable ticket - * @param _maxSubmissionCost Max submission cost for the L2 retryable ticket - * @param _ethAmount Amount of ETH to send with the retryable ticket - */ - function _transferDelegationToL2( - address _delegator, - address _indexer, - address _l2Beneficiary, - uint256 _maxGas, - uint256 _gasPriceBid, - uint256 _maxSubmissionCost, - uint256 _ethAmount - ) internal { - require(_l2Beneficiary != address(0), "l2Beneficiary == 0"); - require(indexerTransferredToL2[_indexer] != address(0), "indexer not transferred"); - - // Get the delegation pool of the indexer - DelegationPool storage pool = __delegationPools[_indexer]; - Delegation storage delegation = pool.delegators[_delegator]; - - // Check that the delegation is not locked for undelegation - require(delegation.tokensLocked == 0, "tokensLocked != 0"); - require(delegation.shares != 0, "delegation == 0"); - // Calculate tokens to get in exchange for the shares - uint256 tokensToSend = delegation.shares.mul(pool.tokens).div(pool.shares); - - // Update the delegation pool - pool.tokens = pool.tokens.sub(tokensToSend); - pool.shares = pool.shares.sub(delegation.shares); - - // Update the delegation - delegation.shares = 0; - bytes memory extraData; - { - IL2StakingTypes.ReceiveDelegationData memory functionData; - functionData.indexer = indexerTransferredToL2[_indexer]; - functionData.delegator = _l2Beneficiary; - extraData = abi.encode( - uint8(IL2StakingTypes.L1MessageCodes.RECEIVE_DELEGATION_CODE), - abi.encode(functionData) - ); - } - - _sendTokensAndMessageToL2Staking( - tokensToSend, - _maxGas, - _gasPriceBid, - _maxSubmissionCost, - _ethAmount, - extraData - ); - emit DelegationTransferredToL2( - _delegator, - _l2Beneficiary, - _indexer, - indexerTransferredToL2[_indexer], - tokensToSend - ); - } - - /** - * @notice Sends a message to the L2Staking with some extra data, - * also sending some tokens, using the L1GraphTokenGateway. - * @param _tokens Amount of tokens to send to L2 - * @param _maxGas Max gas to use for the L2 retryable ticket - * @param _gasPriceBid Gas price bid for the L2 retryable ticket - * @param _maxSubmissionCost Max submission cost for the L2 retryable ticket - * @param _value Amount of ETH to send with the message - * @param _extraData Extra data for the callhook on L2Staking - */ - function _sendTokensAndMessageToL2Staking( - uint256 _tokens, - uint256 _maxGas, - uint256 _gasPriceBid, - uint256 _maxSubmissionCost, - uint256 _value, - bytes memory _extraData - ) internal { - IGraphToken grt = graphToken(); - ITokenGateway gateway = graphTokenGateway(); - grt.approve(address(gateway), _tokens); - gateway.outboundTransfer{ value: _value }( - address(grt), - counterpartStakingAddress, - _tokens, - _maxGas, - _gasPriceBid, - abi.encode(_maxSubmissionCost, _extraData) - ); - } -} diff --git a/packages/contracts/contracts/staking/L1StakingStorage.sol b/packages/contracts/contracts/staking/L1StakingStorage.sol deleted file mode 100644 index 5ee76f633..000000000 --- a/packages/contracts/contracts/staking/L1StakingStorage.sol +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable named-parameters-mapping - -pragma solidity ^0.7.6; -pragma abicoder v2; - -import { IL1GraphTokenLockTransferTool } from "@graphprotocol/interfaces/contracts/contracts/staking/IL1GraphTokenLockTransferTool.sol"; - -/** - * @title L1StakingV1Storage - * @author Edge & Node - * @notice This contract holds all the L1-specific storage variables for the L1Staking contract, version 1 - * @dev When adding new versions, make sure to move the gap to the new version and - * reduce the size of the gap accordingly. - */ -abstract contract L1StakingV1Storage { - /// @notice If an indexer has transferred to L2, this mapping will hold the indexer's address in L2 - mapping(address => address) public indexerTransferredToL2; - /// @dev For locked indexers/delegations, this contract holds the mapping of L1 to L2 addresses - IL1GraphTokenLockTransferTool internal l1GraphTokenLockTransferTool; - /// @dev Storage gap to keep storage slots fixed in future versions - uint256[50] private __gap; -} diff --git a/packages/contracts/contracts/staking/Staking.sol b/packages/contracts/contracts/staking/Staking.sol deleted file mode 100644 index 4b7551d02..000000000 --- a/packages/contracts/contracts/staking/Staking.sol +++ /dev/null @@ -1,975 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable function-max-lines, gas-strict-inequalities - -import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; -import { ECDSA } from "@openzeppelin/contracts/cryptography/ECDSA.sol"; - -import { Multicall } from "../base/Multicall.sol"; -import { GraphUpgradeable } from "../upgrades/GraphUpgradeable.sol"; -import { TokenUtils } from "../utils/TokenUtils.sol"; -import { IGraphToken } from "@graphprotocol/interfaces/contracts/contracts/token/IGraphToken.sol"; -import { IStakingBase } from "@graphprotocol/interfaces/contracts/contracts/staking/IStakingBase.sol"; -import { StakingV4Storage } from "./StakingStorage.sol"; -import { MathUtils } from "./libs/MathUtils.sol"; -import { Stakes } from "./libs/Stakes.sol"; -import { IStakes } from "@graphprotocol/interfaces/contracts/contracts/staking/libs/IStakes.sol"; -import { Managed } from "../governance/Managed.sol"; -import { ICuration } from "@graphprotocol/interfaces/contracts/contracts/curation/ICuration.sol"; -import { IRewardsManager } from "@graphprotocol/interfaces/contracts/contracts/rewards/IRewardsManager.sol"; -import { StakingExtension } from "./StakingExtension.sol"; -import { LibExponential } from "./libs/Exponential.sol"; - -/** - * @title Base Staking contract - * @author Edge & Node - * @notice The Staking contract allows Indexers to Stake on Subgraphs. Indexers Stake by creating - * Allocations on a Subgraph. It also allows Delegators to Delegate towards an Indexer. The - * contract also has the slashing functionality. - * The contract is abstract as the implementation that is deployed depends on each layer: L1Staking on mainnet - * and L2Staking on Arbitrum. - * Note that this contract delegates part of its functionality to a StakingExtension contract. - * This is due to the 24kB contract size limit on Ethereum. - */ -abstract contract Staking is StakingV4Storage, GraphUpgradeable, IStakingBase, Multicall { - using SafeMath for uint256; - using Stakes for IStakes.Indexer; - - /// @dev 100% in parts per million - uint32 internal constant MAX_PPM = 1000000; - - // -- Events are declared in IStakingBase -- // - - /** - * @notice Delegates the current call to the StakingExtension implementation. - * @dev This function does not return to its internal call site, it will return directly to the - * external caller. - */ - fallback() external { - // solhint-disable-previous-line payable-fallback, no-complex-fallback - - require(_implementation() != address(0), "only through proxy"); - - // solhint-disable-next-line no-inline-assembly - assembly { - // (a) get free memory pointer - let ptr := mload(0x40) - - // (b) get address of the implementation - // CAREFUL here: this only works because extensionImpl is the first variable in this slot - // (otherwise we may have to apply an offset) - let impl := and(sload(extensionImpl.slot), 0xffffffffffffffffffffffffffffffffffffffff) - - // (1) copy incoming call data - calldatacopy(ptr, 0, calldatasize()) - - // (2) forward call to logic contract - let result := delegatecall(gas(), impl, ptr, calldatasize(), 0, 0) - let size := returndatasize() - - // (3) retrieve return data - returndatacopy(ptr, 0, size) - - // (4) forward return data back to caller - switch result - case 0 { - revert(ptr, size) - } - default { - return(ptr, size) - } - } - } - - /** - * @inheritdoc IStakingBase - */ - function initialize( - address _controller, - uint256 _minimumIndexerStake, - uint32 _thawingPeriod, - uint32 _protocolPercentage, - uint32 _curationPercentage, - uint32 _maxAllocationEpochs, - uint32 _delegationUnbondingPeriod, - uint32 _delegationRatio, - RebatesParameters calldata _rebatesParameters, - address _extensionImpl - ) external override onlyImpl { - Managed._initialize(_controller); - - // Settings - - _setMinimumIndexerStake(_minimumIndexerStake); - _setThawingPeriod(_thawingPeriod); - - _setProtocolPercentage(_protocolPercentage); - _setCurationPercentage(_curationPercentage); - - _setMaxAllocationEpochs(_maxAllocationEpochs); - - _setRebateParameters( - _rebatesParameters.alphaNumerator, - _rebatesParameters.alphaDenominator, - _rebatesParameters.lambdaNumerator, - _rebatesParameters.lambdaDenominator - ); - - extensionImpl = _extensionImpl; - - // solhint-disable-next-line avoid-low-level-calls - (bool success, ) = extensionImpl.delegatecall( - abi.encodeWithSelector( - StakingExtension.initialize.selector, - _delegationUnbondingPeriod, - 0, - _delegationRatio, - 0 - ) - ); - require(success, "Extension init failed"); - emit ExtensionImplementationSet(_extensionImpl); - } - - /** - * @inheritdoc IStakingBase - */ - function setExtensionImpl(address _extensionImpl) external override onlyGovernor { - extensionImpl = _extensionImpl; - emit ExtensionImplementationSet(_extensionImpl); - } - - /** - * @inheritdoc IStakingBase - */ - function setCounterpartStakingAddress(address _counterpart) external override onlyGovernor { - counterpartStakingAddress = _counterpart; - emit ParameterUpdated("counterpartStakingAddress"); - } - - /** - * @inheritdoc IStakingBase - */ - function setMinimumIndexerStake(uint256 _minimumIndexerStake) external override onlyGovernor { - _setMinimumIndexerStake(_minimumIndexerStake); - } - - /** - * @inheritdoc IStakingBase - */ - function setThawingPeriod(uint32 _thawingPeriod) external override onlyGovernor { - _setThawingPeriod(_thawingPeriod); - } - - /** - * @inheritdoc IStakingBase - */ - function setCurationPercentage(uint32 _percentage) external override onlyGovernor { - _setCurationPercentage(_percentage); - } - - /** - * @inheritdoc IStakingBase - */ - function setProtocolPercentage(uint32 _percentage) external override onlyGovernor { - _setProtocolPercentage(_percentage); - } - - /** - * @inheritdoc IStakingBase - */ - function setMaxAllocationEpochs(uint32 _maxAllocationEpochs) external override onlyGovernor { - _setMaxAllocationEpochs(_maxAllocationEpochs); - } - - /** - * @inheritdoc IStakingBase - */ - function setRebateParameters( - uint32 _alphaNumerator, - uint32 _alphaDenominator, - uint32 _lambdaNumerator, - uint32 _lambdaDenominator - ) external override onlyGovernor { - _setRebateParameters(_alphaNumerator, _alphaDenominator, _lambdaNumerator, _lambdaDenominator); - } - - /** - * @inheritdoc IStakingBase - */ - function setOperator(address _operator, bool _allowed) external override { - require(_operator != msg.sender, "operator == sender"); - __operatorAuth[msg.sender][_operator] = _allowed; - emit SetOperator(msg.sender, _operator, _allowed); - } - - /** - * @inheritdoc IStakingBase - */ - function stake(uint256 _tokens) external override { - stakeTo(msg.sender, _tokens); - } - - /** - * @inheritdoc IStakingBase - * @dev NOTE: The function accepts an amount greater than the currently staked tokens. - * If that happens, it will try to unstake the max amount of tokens it can. - * The reason for this behaviour is to avoid time conditions while the transaction - * is in flight. - */ - function unstake(uint256 _tokens) external override notPartialPaused { - address indexer = msg.sender; - IStakes.Indexer storage indexerStake = __stakes[indexer]; - - require(indexerStake.tokensStaked > 0, "!stake"); - - // Tokens to lock is capped to the available tokens - uint256 tokensToLock = MathUtils.min(indexerStake.tokensAvailable(), _tokens); - require(tokensToLock > 0, "!stake-avail"); - - // Ensure minimum stake - uint256 newStake = indexerStake.tokensSecureStake().sub(tokensToLock); - require(newStake == 0 || newStake >= __minimumIndexerStake, "!minimumIndexerStake"); - - // Before locking more tokens, withdraw any unlocked ones if possible - uint256 tokensToWithdraw = indexerStake.tokensWithdrawable(); - if (tokensToWithdraw > 0) { - _withdraw(indexer); - } - - // Update the indexer stake locking tokens - indexerStake.lockTokens(tokensToLock, __thawingPeriod); - - emit StakeLocked(indexer, indexerStake.tokensLocked, indexerStake.tokensLockedUntil); - } - - /** - * @inheritdoc IStakingBase - */ - function withdraw() external override notPaused { - _withdraw(msg.sender); - } - - /** - * @inheritdoc IStakingBase - */ - function setRewardsDestination(address _destination) external override { - __rewardsDestination[msg.sender] = _destination; - emit SetRewardsDestination(msg.sender, _destination); - } - - /** - * @inheritdoc IStakingBase - */ - function allocate( - bytes32 _subgraphDeploymentID, - uint256 _tokens, - address _allocationID, - bytes32 _metadata, - bytes calldata _proof - ) external override notPaused { - _allocate(msg.sender, _subgraphDeploymentID, _tokens, _allocationID, _metadata, _proof); - } - - /** - * @inheritdoc IStakingBase - */ - function allocateFrom( - address _indexer, - bytes32 _subgraphDeploymentID, - uint256 _tokens, - address _allocationID, - bytes32 _metadata, - bytes calldata _proof - ) external override notPaused { - _allocate(_indexer, _subgraphDeploymentID, _tokens, _allocationID, _metadata, _proof); - } - - /** - * @inheritdoc IStakingBase - * @dev To be eligible for rewards a proof of indexing must be presented. - * Presenting a bad proof is subject to slashable condition. - * To opt out of rewards set _poi to 0x0 - */ - function closeAllocation(address _allocationID, bytes32 _poi) external override notPaused { - _closeAllocation(_allocationID, _poi); - } - - /** - * @inheritdoc IStakingBase - * @dev We use an exponential rebate formula to calculate the amount of tokens to rebate to the indexer. - * This implementation allows collecting multiple times on the same allocation, keeping track of the - * total amount rebated, the total amount collected and compensating the indexer for the difference. - */ - function collect(uint256 _tokens, address _allocationID) external override { - // Allocation identifier validation - require(_allocationID != address(0), "!alloc"); - - // Allocation must exist - AllocationState allocState = _getAllocationState(_allocationID); - require(allocState != AllocationState.Null, "!collect"); - - // If the query fees are zero, we don't want to revert - // but we also don't need to do anything, so just return - if (_tokens == 0) { - return; - } - - Allocation storage alloc = __allocations[_allocationID]; - bytes32 subgraphDeploymentID = alloc.subgraphDeploymentID; - - uint256 queryFees = _tokens; // Tokens collected from the channel - uint256 protocolTax = 0; // Tokens burnt as protocol tax - uint256 curationFees = 0; // Tokens distributed to curators as curation fees - uint256 queryRebates = 0; // Tokens to distribute to indexer - uint256 delegationRewards = 0; // Tokens to distribute to delegators - - { - // -- Pull tokens from the sender -- - IGraphToken graphToken = graphToken(); - TokenUtils.pullTokens(graphToken, msg.sender, queryFees); - - // -- Collect protocol tax -- - protocolTax = _collectTax(graphToken, queryFees, __protocolPercentage); - queryFees = queryFees.sub(protocolTax); - - // -- Collect curation fees -- - // Only if the subgraph deployment is curated - curationFees = _collectCurationFees(graphToken, subgraphDeploymentID, queryFees, __curationPercentage); - queryFees = queryFees.sub(curationFees); - - // -- Process rebate reward -- - // Using accumulated fees and subtracting previously distributed rebates - // allows for multiple vouchers to be collected while following the rebate formula - alloc.collectedFees = alloc.collectedFees.add(queryFees); - - // No rebates if indexer has no stake or if lambda is zero - uint256 newRebates = (alloc.tokens == 0 || __lambdaNumerator == 0) - ? 0 - : LibExponential.exponentialRebates( - alloc.collectedFees, - alloc.tokens, - __alphaNumerator, - __alphaDenominator, - __lambdaNumerator, - __lambdaDenominator - ); - - // -- Ensure rebates to distribute are within bounds -- - // Indexers can become under or over rebated if rebate parameters (alpha, lambda) - // change between successive collect calls for the same allocation - - // Ensure rebates to distribute are not negative (indexer is over-rebated) - queryRebates = MathUtils.diffOrZero(newRebates, alloc.distributedRebates); - - // Ensure rebates to distribute are not greater than available (indexer is under-rebated) - queryRebates = MathUtils.min(queryRebates, queryFees); - - // -- Burn rebates remanent -- - TokenUtils.burnTokens(graphToken, queryFees.sub(queryRebates)); - - // -- Distribute rebates -- - if (queryRebates > 0) { - alloc.distributedRebates = alloc.distributedRebates.add(queryRebates); - - // -- Collect delegation rewards into the delegation pool -- - delegationRewards = _collectDelegationQueryRewards(alloc.indexer, queryRebates); - queryRebates = queryRebates.sub(delegationRewards); - - // -- Transfer or restake rebates -- - _sendRewards( - graphToken, - queryRebates, - alloc.indexer, - __rewardsDestination[alloc.indexer] == address(0) - ); - } - } - - emit RebateCollected( - msg.sender, - alloc.indexer, - subgraphDeploymentID, - _allocationID, - epochManager().currentEpoch(), - _tokens, - protocolTax, - curationFees, - queryFees, - queryRebates, - delegationRewards - ); - } - - /** - * @inheritdoc IStakingBase - */ - function isAllocation(address _allocationID) external view override returns (bool) { - return _getAllocationState(_allocationID) != AllocationState.Null; - } - - /** - * @inheritdoc IStakingBase - */ - function hasStake(address _indexer) external view override returns (bool) { - return __stakes[_indexer].tokensStaked > 0; - } - - /** - * @inheritdoc IStakingBase - */ - function getAllocation(address _allocationID) external view override returns (Allocation memory) { - return __allocations[_allocationID]; - } - - /** - * @inheritdoc IStakingBase - */ - function getAllocationData( - address _allocationID - ) external view override returns (bool, address, bytes32, uint256, uint256, uint256) { - Allocation memory alloc = __allocations[_allocationID]; - bool isActive = _getAllocationState(_allocationID) == AllocationState.Active; - - return ( - isActive, - alloc.indexer, - alloc.subgraphDeploymentID, - alloc.tokens, - alloc.accRewardsPerAllocatedToken, - 0 - ); - } - - /** - * @inheritdoc IStakingBase - */ - function isActiveAllocation(address _allocationID) external view override returns (bool) { - return _getAllocationState(_allocationID) == AllocationState.Active; - } - - /** - * @inheritdoc IStakingBase - */ - function getAllocationState(address _allocationID) external view override returns (AllocationState) { - return _getAllocationState(_allocationID); - } - - /** - * @inheritdoc IStakingBase - */ - function getSubgraphAllocatedTokens(bytes32 _subgraphDeploymentID) external view override returns (uint256) { - return __subgraphAllocations[_subgraphDeploymentID]; - } - - /** - * @inheritdoc IStakingBase - */ - function getIndexerStakedTokens(address _indexer) external view override returns (uint256) { - return __stakes[_indexer].tokensStaked; - } - - /** - * @inheritdoc IStakingBase - */ - function stakeTo(address _indexer, uint256 _tokens) public override notPartialPaused { - require(_tokens > 0, "!tokens"); - - // Transfer tokens to stake from caller to this contract - TokenUtils.pullTokens(graphToken(), msg.sender, _tokens); - - // Stake the transferred tokens - _stake(_indexer, _tokens); - } - - /** - * @inheritdoc IStakingBase - */ - function setDelegationParameters( - uint32 _indexingRewardCut, - uint32 _queryFeeCut, - uint32 // _cooldownBlocks, deprecated - ) public override { - _setDelegationParameters(msg.sender, _indexingRewardCut, _queryFeeCut); - } - - /** - * @inheritdoc IStakingBase - */ - function getIndexerCapacity(address _indexer) public view override returns (uint256) { - IStakes.Indexer memory indexerStake = __stakes[_indexer]; - uint256 tokensDelegated = __delegationPools[_indexer].tokens; - - uint256 tokensDelegatedCap = indexerStake.tokensSecureStake().mul(uint256(__delegationRatio)); - uint256 tokensDelegatedCapacity = MathUtils.min(tokensDelegated, tokensDelegatedCap); - - return indexerStake.tokensAvailableWithDelegation(tokensDelegatedCapacity); - } - - /** - * @inheritdoc IStakingBase - */ - function isOperator(address _operator, address _indexer) public view override returns (bool) { - return __operatorAuth[_indexer][_operator]; - } - - /** - * @notice Internal: Set the minimum indexer stake required. - * @param _minimumIndexerStake Minimum indexer stake - */ - function _setMinimumIndexerStake(uint256 _minimumIndexerStake) private { - require(_minimumIndexerStake > 0, "!minimumIndexerStake"); - __minimumIndexerStake = _minimumIndexerStake; - emit ParameterUpdated("minimumIndexerStake"); - } - - /** - * @notice Internal: Set the thawing period for unstaking. - * @param _thawingPeriod Period in blocks to wait for token withdrawals after unstaking - */ - function _setThawingPeriod(uint32 _thawingPeriod) private { - require(_thawingPeriod > 0, "!thawingPeriod"); - __thawingPeriod = _thawingPeriod; - emit ParameterUpdated("thawingPeriod"); - } - - /** - * @notice Internal: Set the curation percentage of query fees sent to curators. - * @param _percentage Percentage of query fees sent to curators - */ - function _setCurationPercentage(uint32 _percentage) private { - // Must be within 0% to 100% (inclusive) - require(_percentage <= MAX_PPM, ">percentage"); - __curationPercentage = _percentage; - emit ParameterUpdated("curationPercentage"); - } - - /** - * @notice Internal: Set a protocol percentage to burn when collecting query fees. - * @param _percentage Percentage of query fees to burn as protocol fee - */ - function _setProtocolPercentage(uint32 _percentage) private { - // Must be within 0% to 100% (inclusive) - require(_percentage <= MAX_PPM, ">percentage"); - __protocolPercentage = _percentage; - emit ParameterUpdated("protocolPercentage"); - } - - /** - * @notice Internal: Set the max time allowed for indexers stake on allocations. - * @param _maxAllocationEpochs Allocation duration limit in epochs - */ - function _setMaxAllocationEpochs(uint32 _maxAllocationEpochs) private { - __maxAllocationEpochs = _maxAllocationEpochs; - emit ParameterUpdated("maxAllocationEpochs"); - } - - /** - * @notice Set the rebate parameters. - * @param _alphaNumerator Numerator of `alpha` in the rebates function - * @param _alphaDenominator Denominator of `alpha` in the rebates function - * @param _lambdaNumerator Numerator of `lambda` in the rebates function - * @param _lambdaDenominator Denominator of `lambda` in the rebates function - */ - function _setRebateParameters( - uint32 _alphaNumerator, - uint32 _alphaDenominator, - uint32 _lambdaNumerator, - uint32 _lambdaDenominator - ) private { - require(_alphaDenominator > 0, "!alphaDenominator"); - require(_lambdaNumerator > 0, "!lambdaNumerator"); - require(_lambdaDenominator > 0, "!lambdaDenominator"); - __alphaNumerator = _alphaNumerator; - __alphaDenominator = _alphaDenominator; - __lambdaNumerator = _lambdaNumerator; - __lambdaDenominator = _lambdaDenominator; - emit ParameterUpdated("rebateParameters"); - } - - /** - * @notice Set the delegation parameters for a particular indexer. - * @param _indexer Indexer to set delegation parameters - * @param _indexingRewardCut Percentage of indexing rewards left for delegators - * @param _queryFeeCut Percentage of query fees left for delegators - */ - function _setDelegationParameters(address _indexer, uint32 _indexingRewardCut, uint32 _queryFeeCut) internal { - // Incentives must be within bounds - require(_queryFeeCut <= MAX_PPM, ">queryFeeCut"); - require(_indexingRewardCut <= MAX_PPM, ">indexingRewardCut"); - - DelegationPool storage pool = __delegationPools[_indexer]; - - // Update delegation params - pool.indexingRewardCut = _indexingRewardCut; - pool.queryFeeCut = _queryFeeCut; - pool.updatedAtBlock = block.number; - - emit DelegationParametersUpdated(_indexer, _indexingRewardCut, _queryFeeCut, 0); - } - - /** - * @notice Stake tokens on the indexer. - * This function does not check minimum indexer stake requirement to allow - * to be called by functions that increase the stake when collecting rewards - * without reverting - * @param _indexer Address of staking party - * @param _tokens Amount of tokens to stake - */ - function _stake(address _indexer, uint256 _tokens) internal { - // Ensure minimum stake - require(__stakes[_indexer].tokensSecureStake().add(_tokens) >= __minimumIndexerStake, "!minimumIndexerStake"); - - // Deposit tokens into the indexer stake - __stakes[_indexer].deposit(_tokens); - - // Initialize the delegation pool the first time - if (__delegationPools[_indexer].updatedAtBlock == 0) { - _setDelegationParameters(_indexer, MAX_PPM, MAX_PPM); - } - - emit StakeDeposited(_indexer, _tokens); - } - - /** - * @notice Withdraw indexer tokens once the thawing period has passed. - * @param _indexer Address of indexer to withdraw funds from - */ - function _withdraw(address _indexer) private { - // Get tokens available for withdraw and update balance - uint256 tokensToWithdraw = __stakes[_indexer].withdrawTokens(); - require(tokensToWithdraw > 0, "!tokens"); - - // Return tokens to the indexer - TokenUtils.pushTokens(graphToken(), _indexer, tokensToWithdraw); - - emit StakeWithdrawn(_indexer, tokensToWithdraw); - } - - /** - * @notice Allocate available tokens to a subgraph deployment. - * @param _indexer Indexer address to allocate funds from. - * @param _subgraphDeploymentID ID of the SubgraphDeployment where tokens will be allocated - * @param _tokens Amount of tokens to allocate - * @param _allocationID The allocationID will work to identify collected funds related to this allocation - * @param _metadata Metadata related to the allocation - * @param _proof A 65-bytes Ethereum signed message of `keccak256(indexerAddress,allocationID)` - */ - function _allocate( - address _indexer, - bytes32 _subgraphDeploymentID, - uint256 _tokens, - address _allocationID, - bytes32 _metadata, - bytes calldata _proof - ) private { - require(_isAuth(_indexer), "!auth"); - - // Check allocation - require(_allocationID != address(0), "!alloc"); - require(_getAllocationState(_allocationID) == AllocationState.Null, "!null"); - - // Caller must prove that they own the private key for the allocationID address - // The proof is an Ethereum signed message of KECCAK256(indexerAddress,allocationID) - bytes32 messageHash = keccak256(abi.encodePacked(_indexer, _allocationID)); - bytes32 digest = ECDSA.toEthSignedMessageHash(messageHash); - require(ECDSA.recover(digest, _proof) == _allocationID, "!proof"); - - require(__stakes[_indexer].tokensSecureStake() >= __minimumIndexerStake, "!minimumIndexerStake"); - if (_tokens > 0) { - // Needs to have free capacity not used for other purposes to allocate - require(getIndexerCapacity(_indexer) >= _tokens, "!capacity"); - } - - // Creates an allocation - // Allocation identifiers are not reused - // Anyone can send collected funds to the allocation using collect() - Allocation memory alloc = Allocation( - _indexer, - _subgraphDeploymentID, - _tokens, // Tokens allocated - epochManager().currentEpoch(), // createdAtEpoch - 0, // closedAtEpoch - 0, // Initialize collected fees - 0, // Initialize effective allocation (DEPRECATED) - (_tokens > 0) ? _updateRewards(_subgraphDeploymentID) : 0, // Initialize accumulated rewards per stake allocated - 0 // Initialize distributed rebates - ); - __allocations[_allocationID] = alloc; - - // -- Rewards Distribution -- - - // Process non-zero-allocation rewards tracking - if (_tokens > 0) { - // Mark allocated tokens as used - __stakes[_indexer].allocate(alloc.tokens); - - // Track total allocations per subgraph - // Used for rewards calculations - __subgraphAllocations[alloc.subgraphDeploymentID] = __subgraphAllocations[alloc.subgraphDeploymentID].add( - alloc.tokens - ); - } - - emit AllocationCreated( - _indexer, - _subgraphDeploymentID, - alloc.createdAtEpoch, - alloc.tokens, - _allocationID, - _metadata - ); - } - - /** - * @notice Close an allocation and free the staked tokens. - * @param _allocationID The allocation identifier - * @param _poi Proof of indexing submitted for the allocated period - */ - function _closeAllocation(address _allocationID, bytes32 _poi) private { - // Allocation must exist and be active - AllocationState allocState = _getAllocationState(_allocationID); - require(allocState == AllocationState.Active, "!active"); - - // Get allocation - Allocation memory alloc = __allocations[_allocationID]; - - alloc.closedAtEpoch = epochManager().currentEpoch(); - - // Allocation duration in epochs - uint256 epochs = MathUtils.diffOrZero(alloc.closedAtEpoch, alloc.createdAtEpoch); - - // Indexer or operator can close an allocation - // Anyone is allowed to close ONLY under two concurrent conditions - // - After maxAllocationEpochs passed - // - When the allocation is for non-zero amount of tokens - bool isIndexerOrOperator = _isAuth(alloc.indexer); - if (epochs <= __maxAllocationEpochs || alloc.tokens == 0) { - require(isIndexerOrOperator, "!auth"); - } - - // -- Rewards Distribution -- - - // Process non-zero-allocation rewards tracking - if (alloc.tokens > 0) { - // Distribute rewards if proof of indexing was presented by the indexer or operator - // and the allocation is at least one epoch old (most indexed chains require the EBO - // posting epoch block numbers to produce a valid POI which happens once per epoch) - if (isIndexerOrOperator && _poi != 0 && epochs > 0) { - _distributeRewards(_allocationID, alloc.indexer); - } else { - _updateRewards(alloc.subgraphDeploymentID); - } - - // Free allocated tokens from use - __stakes[alloc.indexer].unallocate(alloc.tokens); - - // Track total allocations per subgraph - // Used for rewards calculations - __subgraphAllocations[alloc.subgraphDeploymentID] = __subgraphAllocations[alloc.subgraphDeploymentID].sub( - alloc.tokens - ); - } - - // Close the allocation - // Note that this breaks CEI pattern. We update after the rewards distribution logic as it expects the allocation - // to still be active. There shouldn't be reentrancy risk here as all internal calls are to trusted contracts. - __allocations[_allocationID].closedAtEpoch = alloc.closedAtEpoch; - - emit AllocationClosed( - alloc.indexer, - alloc.subgraphDeploymentID, - alloc.closedAtEpoch, - alloc.tokens, - _allocationID, - msg.sender, - _poi, - !isIndexerOrOperator - ); - } - - /** - * @notice Collect the delegation rewards for query fees. - * This function will assign the collected fees to the delegation pool. - * @param _indexer Indexer to which the tokens to distribute are related - * @param _tokens Total tokens received used to calculate the amount of fees to collect - * @return Amount of delegation rewards - */ - function _collectDelegationQueryRewards(address _indexer, uint256 _tokens) private returns (uint256) { - uint256 delegationRewards = 0; - DelegationPool storage pool = __delegationPools[_indexer]; - if (pool.tokens > 0 && pool.queryFeeCut < MAX_PPM) { - uint256 indexerCut = uint256(pool.queryFeeCut).mul(_tokens).div(MAX_PPM); - delegationRewards = _tokens.sub(indexerCut); - pool.tokens = pool.tokens.add(delegationRewards); - } - return delegationRewards; - } - - /** - * @notice Collect the delegation rewards for indexing. - * This function will assign the collected fees to the delegation pool. - * @param _indexer Indexer to which the tokens to distribute are related - * @param _tokens Total tokens received used to calculate the amount of fees to collect - * @return Amount of delegation rewards - */ - function _collectDelegationIndexingRewards(address _indexer, uint256 _tokens) private returns (uint256) { - uint256 delegationRewards = 0; - DelegationPool storage pool = __delegationPools[_indexer]; - if (pool.tokens > 0 && pool.indexingRewardCut < MAX_PPM) { - uint256 indexerCut = uint256(pool.indexingRewardCut).mul(_tokens).div(MAX_PPM); - delegationRewards = _tokens.sub(indexerCut); - pool.tokens = pool.tokens.add(delegationRewards); - } - return delegationRewards; - } - - /** - * @notice Collect the curation fees for a subgraph deployment from an amount of tokens. - * This function transfer curation fees to the Curation contract by calling Curation.collect - * @param _graphToken Token to collect - * @param _subgraphDeploymentID Subgraph deployment to which the curation fees are related - * @param _tokens Total tokens received used to calculate the amount of fees to collect - * @param _curationPercentage Percentage of tokens to collect as fees - * @return Amount of curation fees - */ - function _collectCurationFees( - IGraphToken _graphToken, - bytes32 _subgraphDeploymentID, - uint256 _tokens, - uint256 _curationPercentage - ) private returns (uint256) { - if (_tokens == 0) { - return 0; - } - - ICuration curation = curation(); - bool isCurationEnabled = _curationPercentage > 0 && address(curation) != address(0); - - if (isCurationEnabled && curation.isCurated(_subgraphDeploymentID)) { - // Calculate the tokens after curation fees first, and subtact that, - // to prevent curation fees from rounding down to zero - uint256 tokensAfterCurationFees = uint256(MAX_PPM).sub(_curationPercentage).mul(_tokens).div(MAX_PPM); - uint256 curationFees = _tokens.sub(tokensAfterCurationFees); - if (curationFees > 0) { - // Transfer and call collect() - // This function transfer tokens to a trusted protocol contracts - // Then we call collect() to do the transfer bookkeeping - rewardsManager().onSubgraphSignalUpdate(_subgraphDeploymentID); - TokenUtils.pushTokens(_graphToken, address(curation), curationFees); - curation.collect(_subgraphDeploymentID, curationFees); - } - return curationFees; - } - return 0; - } - - /** - * @notice Collect tax to burn for an amount of tokens. - * @param _graphToken Token to burn - * @param _tokens Total tokens received used to calculate the amount of tax to collect - * @param _percentage Percentage of tokens to burn as tax - * @return Amount of tax charged - */ - function _collectTax(IGraphToken _graphToken, uint256 _tokens, uint256 _percentage) private returns (uint256) { - // Calculate tokens after tax first, and subtract that, - // to prevent the tax from rounding down to zero - uint256 tokensAfterTax = uint256(MAX_PPM).sub(_percentage).mul(_tokens).div(MAX_PPM); - uint256 tax = _tokens.sub(tokensAfterTax); - TokenUtils.burnTokens(_graphToken, tax); // Burn tax if any - return tax; - } - - /** - * @notice Triggers an update of rewards due to a change in allocations. - * @param _subgraphDeploymentID Subgraph deployment updated - * @return Accumulated rewards per allocated token for the subgraph deployment - */ - function _updateRewards(bytes32 _subgraphDeploymentID) private returns (uint256) { - IRewardsManager rewardsManager = rewardsManager(); - if (address(rewardsManager) == address(0)) { - return 0; - } - return rewardsManager.onSubgraphAllocationUpdate(_subgraphDeploymentID); - } - - /** - * @notice Assign rewards for the closed allocation to indexer and delegators. - * @param _allocationID Allocation - * @param _indexer Address of the indexer that did the allocation - */ - function _distributeRewards(address _allocationID, address _indexer) private { - IRewardsManager rewardsManager = rewardsManager(); - if (address(rewardsManager) == address(0)) { - return; - } - - // Automatically triggers update of rewards snapshot as allocation will change - // after this call. Take rewards mint tokens for the Staking contract to distribute - // between indexer and delegators - uint256 totalRewards = rewardsManager.takeRewards(_allocationID); - if (totalRewards == 0) { - return; - } - - // Calculate delegation rewards and add them to the delegation pool - uint256 delegationRewards = _collectDelegationIndexingRewards(_indexer, totalRewards); - uint256 indexerRewards = totalRewards.sub(delegationRewards); - - // Send the indexer rewards - _sendRewards(graphToken(), indexerRewards, _indexer, __rewardsDestination[_indexer] == address(0)); - } - - /** - * @notice Send rewards to the appropriate destination. - * @param _graphToken Graph token - * @param _amount Number of rewards tokens - * @param _beneficiary Address of the beneficiary of rewards - * @param _restake Whether to restake or not - */ - function _sendRewards(IGraphToken _graphToken, uint256 _amount, address _beneficiary, bool _restake) private { - if (_amount == 0) return; - - if (_restake) { - // Restake to place fees into the indexer stake - _stake(_beneficiary, _amount); - } else { - // Transfer funds to the beneficiary's designated rewards destination if set - address destination = __rewardsDestination[_beneficiary]; - TokenUtils.pushTokens(_graphToken, destination == address(0) ? _beneficiary : destination, _amount); - } - } - - /** - * @notice Check if the caller is authorized to operate on behalf of - * an indexer (i.e. the caller is the indexer or an operator) - * @param _indexer Indexer address - * @return True if the caller is authorized to operate on behalf of the indexer - */ - function _isAuth(address _indexer) private view returns (bool) { - return msg.sender == _indexer || isOperator(msg.sender, _indexer) == true; - } - - /** - * @notice Return the current state of an allocation - * @param _allocationID Allocation identifier - * @return AllocationState enum with the state of the allocation - */ - function _getAllocationState(address _allocationID) private view returns (AllocationState) { - Allocation storage alloc = __allocations[_allocationID]; - - if (alloc.indexer == address(0)) { - return AllocationState.Null; - } - - if (alloc.createdAtEpoch != 0 && alloc.closedAtEpoch == 0) { - return AllocationState.Active; - } - - return AllocationState.Closed; - } -} diff --git a/packages/contracts/contracts/staking/StakingExtension.sol b/packages/contracts/contracts/staking/StakingExtension.sol deleted file mode 100644 index 8bde14add..000000000 --- a/packages/contracts/contracts/staking/StakingExtension.sol +++ /dev/null @@ -1,517 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable gas-strict-inequalities - -import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; -import { StakingV4Storage } from "./StakingStorage.sol"; -import { IStakingExtension } from "@graphprotocol/interfaces/contracts/contracts/staking/IStakingExtension.sol"; -import { TokenUtils } from "../utils/TokenUtils.sol"; -import { IGraphToken } from "@graphprotocol/interfaces/contracts/contracts/token/IGraphToken.sol"; -import { GraphUpgradeable } from "../upgrades/GraphUpgradeable.sol"; -import { IStakes } from "@graphprotocol/interfaces/contracts/contracts/staking/libs/IStakes.sol"; -import { Stakes } from "./libs/Stakes.sol"; -import { IStakingData } from "@graphprotocol/interfaces/contracts/contracts/staking/IStakingData.sol"; -import { MathUtils } from "./libs/MathUtils.sol"; - -/** - * @title StakingExtension contract - * @author Edge & Node - * @notice This contract provides the logic to manage delegations and other Staking - * extension features (e.g. storage getters). It is meant to be called through delegatecall from the - * Staking contract, and is only kept separate to keep the Staking contract size - * within limits. - */ -contract StakingExtension is StakingV4Storage, GraphUpgradeable, IStakingExtension { - using SafeMath for uint256; - using Stakes for IStakes.Indexer; - - /// @dev 100% in parts per million - uint32 private constant MAX_PPM = 1000000; - /// @dev Minimum amount of tokens that can be delegated - uint256 private constant MINIMUM_DELEGATION = 1e18; - - /** - * @dev Check if the caller is the slasher. - */ - modifier onlySlasher() { - require(__slashers[msg.sender] == true, "!slasher"); - _; - } - - /** - * @notice Initialize the StakingExtension contract - * @dev This function is meant to be delegatecalled from the Staking contract's - * initialize() function, so it uses the same access control check to ensure it is - * being called by the Staking implementation as part of the proxy upgrade process. - * @param _delegationUnbondingPeriod Delegation unbonding period in blocks - * @param _cooldownBlocks Deprecated parameter (no longer used) - * @param _delegationRatio Delegation capacity multiplier (e.g. 10 means 10x the indexer stake) - * @param _delegationTaxPercentage Percentage of delegated tokens to burn as delegation tax, expressed in parts per million - */ - function initialize( - uint32 _delegationUnbondingPeriod, - // solhint-disable-next-line no-unused-vars - uint32 _cooldownBlocks, // deprecated - uint32 _delegationRatio, - uint32 _delegationTaxPercentage - ) external onlyImpl { - _setDelegationUnbondingPeriod(_delegationUnbondingPeriod); - _setDelegationRatio(_delegationRatio); - _setDelegationTaxPercentage(_delegationTaxPercentage); - } - - /** - * @inheritdoc IStakingExtension - */ - function setDelegationTaxPercentage(uint32 _percentage) external override onlyGovernor { - _setDelegationTaxPercentage(_percentage); - } - - /** - * @inheritdoc IStakingExtension - */ - function setDelegationRatio(uint32 _delegationRatio) external override onlyGovernor { - _setDelegationRatio(_delegationRatio); - } - - /** - * @inheritdoc IStakingExtension - */ - function setDelegationUnbondingPeriod(uint32 _delegationUnbondingPeriod) external override onlyGovernor { - _setDelegationUnbondingPeriod(_delegationUnbondingPeriod); - } - - /** - * @inheritdoc IStakingExtension - */ - function setSlasher(address _slasher, bool _allowed) external override onlyGovernor { - require(_slasher != address(0), "!slasher"); - __slashers[_slasher] = _allowed; - emit SlasherUpdate(msg.sender, _slasher, _allowed); - } - - /** - * @inheritdoc IStakingExtension - */ - function delegate(address _indexer, uint256 _tokens) external override notPartialPaused returns (uint256) { - address delegator = msg.sender; - - // Transfer tokens to delegate to this contract - TokenUtils.pullTokens(graphToken(), delegator, _tokens); - - // Update state - return _delegate(delegator, _indexer, _tokens); - } - - /** - * @inheritdoc IStakingExtension - */ - function undelegate(address _indexer, uint256 _shares) external override notPartialPaused returns (uint256) { - return _undelegate(msg.sender, _indexer, _shares); - } - - /** - * @inheritdoc IStakingExtension - */ - function withdrawDelegated(address _indexer, address _newIndexer) external override notPaused returns (uint256) { - return _withdrawDelegated(msg.sender, _indexer, _newIndexer); - } - - /** - * @inheritdoc IStakingExtension - */ - function slash( - address _indexer, - uint256 _tokens, - uint256 _reward, - address _beneficiary - ) external override onlySlasher notPartialPaused { - IStakes.Indexer storage indexerStake = __stakes[_indexer]; - - // Only able to slash a non-zero number of tokens - require(_tokens > 0, "!tokens"); - - // Rewards comes from tokens slashed balance - require(_tokens >= _reward, "rewards>slash"); - - // Cannot slash stake of an indexer without any or enough stake - require(indexerStake.tokensStaked > 0, "!stake"); - require(_tokens <= indexerStake.tokensStaked, "slash>stake"); - - // Validate beneficiary of slashed tokens - require(_beneficiary != address(0), "!beneficiary"); - - // Slashing more tokens than freely available (over allocation condition) - // Unlock locked tokens to avoid the indexer to withdraw them - if (_tokens > indexerStake.tokensAvailable() && indexerStake.tokensLocked > 0) { - uint256 tokensOverAllocated = _tokens.sub(indexerStake.tokensAvailable()); - uint256 tokensToUnlock = MathUtils.min(tokensOverAllocated, indexerStake.tokensLocked); - indexerStake.unlockTokens(tokensToUnlock); - } - - // Remove tokens to slash from the stake - indexerStake.release(_tokens); - - // -- Interactions -- - - IGraphToken graphToken = graphToken(); - - // Set apart the reward for the beneficiary and burn remaining slashed stake - TokenUtils.burnTokens(graphToken, _tokens.sub(_reward)); - - // Give the beneficiary a reward for slashing - TokenUtils.pushTokens(graphToken, _beneficiary, _reward); - - emit StakeSlashed(_indexer, _tokens, _reward, _beneficiary); - } - - /** - * @inheritdoc IStakingExtension - */ - function getDelegation(address _indexer, address _delegator) external view override returns (Delegation memory) { - return __delegationPools[_indexer].delegators[_delegator]; - } - - /** - * @inheritdoc IStakingExtension - */ - function delegationRatio() external view override returns (uint32) { - return __delegationRatio; - } - - /** - * @inheritdoc IStakingExtension - */ - function delegationUnbondingPeriod() external view override returns (uint32) { - return __delegationUnbondingPeriod; - } - - /** - * @inheritdoc IStakingExtension - */ - function delegationTaxPercentage() external view override returns (uint32) { - return __delegationTaxPercentage; - } - - /** - * @inheritdoc IStakingExtension - */ - function delegationPools(address _indexer) external view override returns (DelegationPoolReturn memory) { - DelegationPool storage pool = __delegationPools[_indexer]; - return - DelegationPoolReturn( - 0, // Blocks to wait before updating parameters (deprecated) - pool.indexingRewardCut, // in PPM - pool.queryFeeCut, // in PPM - pool.updatedAtBlock, // Block when the pool was last updated - pool.tokens, // Total tokens as pool reserves - pool.shares // Total shares minted in the pool - ); - } - - /** - * @inheritdoc IStakingExtension - */ - function rewardsDestination(address _indexer) external view override returns (address) { - return __rewardsDestination[_indexer]; - } - - /** - * @inheritdoc IStakingExtension - */ - function operatorAuth(address _indexer, address _maybeOperator) external view override returns (bool) { - return __operatorAuth[_indexer][_maybeOperator]; - } - - /** - * @inheritdoc IStakingExtension - */ - function subgraphAllocations(bytes32 _subgraphDeploymentId) external view override returns (uint256) { - return __subgraphAllocations[_subgraphDeploymentId]; - } - - /** - * @inheritdoc IStakingExtension - */ - function slashers(address _maybeSlasher) external view override returns (bool) { - return __slashers[_maybeSlasher]; - } - - /** - * @inheritdoc IStakingExtension - */ - function minimumIndexerStake() external view override returns (uint256) { - return __minimumIndexerStake; - } - - /** - * @inheritdoc IStakingExtension - */ - function thawingPeriod() external view override returns (uint32) { - return __thawingPeriod; - } - - /** - * @inheritdoc IStakingExtension - */ - function curationPercentage() external view override returns (uint32) { - return __curationPercentage; - } - - /** - * @inheritdoc IStakingExtension - */ - function protocolPercentage() external view override returns (uint32) { - return __protocolPercentage; - } - - /** - * @inheritdoc IStakingExtension - */ - function maxAllocationEpochs() external view override returns (uint32) { - return __maxAllocationEpochs; - } - - /** - * @inheritdoc IStakingExtension - */ - function alphaNumerator() external view override returns (uint32) { - return __alphaNumerator; - } - - /** - * @inheritdoc IStakingExtension - */ - function alphaDenominator() external view override returns (uint32) { - return __alphaDenominator; - } - - /** - * @inheritdoc IStakingExtension - */ - function lambdaNumerator() external view override returns (uint32) { - return __lambdaNumerator; - } - - /** - * @inheritdoc IStakingExtension - */ - function lambdaDenominator() external view override returns (uint32) { - return __lambdaDenominator; - } - - /** - * @notice Getter for stakes[_indexer]: - * gets the stake information for an indexer as an IStakes.Indexer struct. - * @param _indexer Indexer address for which to query the stake information - * @return Stake information for the specified indexer, as an IStakes.Indexer struct - * @inheritdoc IStakingExtension - */ - function stakes(address _indexer) external view override returns (IStakes.Indexer memory) { - return __stakes[_indexer]; - } - - /** - * @inheritdoc IStakingExtension - */ - function allocations(address _allocationID) external view override returns (IStakingData.Allocation memory) { - return __allocations[_allocationID]; - } - - /** - * @inheritdoc IStakingExtension - */ - function isDelegator(address _indexer, address _delegator) public view override returns (bool) { - return __delegationPools[_indexer].delegators[_delegator].shares > 0; - } - - /** - * @inheritdoc IStakingExtension - */ - function getWithdraweableDelegatedTokens(Delegation memory _delegation) public view override returns (uint256) { - // There must be locked tokens and period passed - uint256 currentEpoch = epochManager().currentEpoch(); - if (_delegation.tokensLockedUntil > 0 && currentEpoch >= _delegation.tokensLockedUntil) { - return _delegation.tokensLocked; - } - return 0; - } - - /** - * @notice Internal: Set a delegation tax percentage to burn when delegated funds are deposited. - * @param _percentage Percentage of delegated tokens to burn as delegation tax - */ - function _setDelegationTaxPercentage(uint32 _percentage) private { - // Must be within 0% to 100% (inclusive) - require(_percentage <= MAX_PPM, ">percentage"); - __delegationTaxPercentage = _percentage; - emit ParameterUpdated("delegationTaxPercentage"); - } - - /** - * @notice Internal: Set the delegation ratio. - * If set to 10 it means the indexer can use up to 10x the indexer staked amount - * from their delegated tokens - * @param _delegationRatio Delegation capacity multiplier - */ - function _setDelegationRatio(uint32 _delegationRatio) private { - __delegationRatio = _delegationRatio; - emit ParameterUpdated("delegationRatio"); - } - - /** - * @notice Internal: Set the period for undelegation of stake from indexer. - * @param _delegationUnbondingPeriod Period in epochs to wait for token withdrawals after undelegating - */ - function _setDelegationUnbondingPeriod(uint32 _delegationUnbondingPeriod) private { - require(_delegationUnbondingPeriod > 0, "!delegationUnbondingPeriod"); - __delegationUnbondingPeriod = _delegationUnbondingPeriod; - emit ParameterUpdated("delegationUnbondingPeriod"); - } - - /** - * @notice Delegate tokens to an indexer. - * @param _delegator Address of the delegator - * @param _indexer Address of the indexer to delegate tokens to - * @param _tokens Amount of tokens to delegate - * @return Amount of shares issued of the delegation pool - */ - function _delegate(address _delegator, address _indexer, uint256 _tokens) private returns (uint256) { - // Only allow delegations over a minimum, to prevent rounding attacks - require(_tokens >= MINIMUM_DELEGATION, "!minimum-delegation"); - // Only delegate to non-empty address - require(_indexer != address(0), "!indexer"); - // Only delegate to staked indexer - require(__stakes[_indexer].tokensStaked > 0, "!stake"); - - // Get the delegation pool of the indexer - DelegationPool storage pool = __delegationPools[_indexer]; - Delegation storage delegation = pool.delegators[_delegator]; - - // Collect delegation tax - uint256 delegationTax = _collectTax(graphToken(), _tokens, __delegationTaxPercentage); - uint256 delegatedTokens = _tokens.sub(delegationTax); - - // Calculate shares to issue - uint256 shares = (pool.tokens == 0) ? delegatedTokens : delegatedTokens.mul(pool.shares).div(pool.tokens); - require(shares > 0, "!shares"); - - // Update the delegation pool - pool.tokens = pool.tokens.add(delegatedTokens); - pool.shares = pool.shares.add(shares); - - // Update the individual delegation - delegation.shares = delegation.shares.add(shares); - - emit StakeDelegated(_indexer, _delegator, delegatedTokens, shares); - - return shares; - } - - /** - * @notice Undelegate tokens from an indexer. - * @param _delegator Address of the delegator - * @param _indexer Address of the indexer where tokens had been delegated - * @param _shares Amount of shares to return and undelegate tokens - * @return Amount of tokens returned for the shares of the delegation pool - */ - function _undelegate(address _delegator, address _indexer, uint256 _shares) private returns (uint256) { - // Can only undelegate a non-zero amount of shares - require(_shares > 0, "!shares"); - - // Get the delegation pool of the indexer - DelegationPool storage pool = __delegationPools[_indexer]; - Delegation storage delegation = pool.delegators[_delegator]; - - // Delegator need to have enough shares in the pool to undelegate - require(delegation.shares >= _shares, "!shares-avail"); - - // Withdraw tokens if available - if (getWithdraweableDelegatedTokens(delegation) > 0) { - _withdrawDelegated(_delegator, _indexer, address(0)); - } - - uint256 poolTokens = pool.tokens; - uint256 poolShares = pool.shares; - - // Calculate tokens to get in exchange for the shares - uint256 tokens = _shares.mul(poolTokens).div(poolShares); - - // Update the delegation pool - poolTokens = poolTokens.sub(tokens); - poolShares = poolShares.sub(_shares); - pool.tokens = poolTokens; - pool.shares = poolShares; - - // Update the delegation - delegation.shares = delegation.shares.sub(_shares); - // Enforce more than the minimum delegation is left, - // to prevent rounding attacks - if (delegation.shares > 0) { - uint256 remainingDelegation = delegation.shares.mul(poolTokens).div(poolShares); - require(remainingDelegation >= MINIMUM_DELEGATION, "!minimum-delegation"); - } - delegation.tokensLocked = delegation.tokensLocked.add(tokens); - delegation.tokensLockedUntil = epochManager().currentEpoch().add(__delegationUnbondingPeriod); - - emit StakeDelegatedLocked(_indexer, _delegator, tokens, _shares, delegation.tokensLockedUntil); - - return tokens; - } - - /** - * @notice Withdraw delegated tokens once the unbonding period has passed. - * @param _delegator Delegator that is withdrawing tokens - * @param _indexer Withdraw available tokens delegated to indexer - * @param _delegateToIndexer Re-delegate to indexer address if non-zero, withdraw if zero address - * @return Amount of tokens withdrawn or re-delegated - */ - function _withdrawDelegated( - address _delegator, - address _indexer, - address _delegateToIndexer - ) private returns (uint256) { - // Get the delegation pool of the indexer - DelegationPool storage pool = __delegationPools[_indexer]; - Delegation storage delegation = pool.delegators[_delegator]; - - // Validation - uint256 tokensToWithdraw = getWithdraweableDelegatedTokens(delegation); - require(tokensToWithdraw > 0, "!tokens"); - - // Reset lock - delegation.tokensLocked = 0; - delegation.tokensLockedUntil = 0; - - emit StakeDelegatedWithdrawn(_indexer, _delegator, tokensToWithdraw); - - // -- Interactions -- - - if (_delegateToIndexer != address(0)) { - // Re-delegate tokens to a new indexer - _delegate(_delegator, _delegateToIndexer, tokensToWithdraw); - } else { - // Return tokens to the delegator - TokenUtils.pushTokens(graphToken(), _delegator, tokensToWithdraw); - } - - return tokensToWithdraw; - } - - /** - * @notice Collect tax to burn for an amount of tokens. - * @param _graphToken Token to burn - * @param _tokens Total tokens received used to calculate the amount of tax to collect - * @param _percentage Percentage of tokens to burn as tax - * @return Amount of tax charged - */ - function _collectTax(IGraphToken _graphToken, uint256 _tokens, uint256 _percentage) private returns (uint256) { - uint256 tax = uint256(_percentage).mul(_tokens).div(MAX_PPM); - TokenUtils.burnTokens(_graphToken, tax); // Burn tax if any - return tax; - } -} diff --git a/packages/contracts/contracts/staking/StakingStorage.sol b/packages/contracts/contracts/staking/StakingStorage.sol deleted file mode 100644 index 24f46009f..000000000 --- a/packages/contracts/contracts/staking/StakingStorage.sol +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -// solhint-disable one-contract-per-file - -pragma solidity ^0.7.6; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable one-contract-per-file, max-states-count -// solhint-disable named-parameters-mapping - -import { Managed } from "../governance/Managed.sol"; - -import { IStakingData } from "@graphprotocol/interfaces/contracts/contracts/staking/IStakingData.sol"; -import { IStakes } from "@graphprotocol/interfaces/contracts/contracts/staking/libs/IStakes.sol"; - -/** - * @title StakingV1Storage - * @author Edge & Node - * @notice This contract holds all the storage variables for the Staking contract, version 1 - * @dev Note that we use a double underscore prefix for variable names; this prefix identifies - * variables that used to be public but are now internal, getters can be found on StakingExtension.sol. - */ -contract StakingV1Storage is Managed { - // -- Staking -- - - /// @dev Minimum amount of tokens an indexer needs to stake - uint256 internal __minimumIndexerStake; - - /// @dev Time in blocks to unstake - uint32 internal __thawingPeriod; // in blocks - - /// @dev Percentage of fees going to curators - /// Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) - uint32 internal __curationPercentage; - - /// @dev Percentage of fees burned as protocol fee - /// Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) - uint32 internal __protocolPercentage; - - /// @dev Period for allocation to be finalized - uint32 private __DEPRECATED_channelDisputeEpochs; // solhint-disable-line var-name-mixedcase - - /// @dev Maximum allocation time - uint32 internal __maxAllocationEpochs; - - /// @dev Rebate alpha numerator - // Originally used for Cobb-Douglas rebates, now used for exponential rebates - uint32 internal __alphaNumerator; - - /// @dev Rebate alpha denominator - // Originally used for Cobb-Douglas rebates, now used for exponential rebates - uint32 internal __alphaDenominator; - - /// @dev Indexer stakes : indexer => Stake - mapping(address => IStakes.Indexer) internal __stakes; - - /// @dev Allocations : allocationID => Allocation - mapping(address => IStakingData.Allocation) internal __allocations; - - /// @dev Subgraph Allocations: subgraphDeploymentID => tokens - mapping(bytes32 => uint256) internal __subgraphAllocations; - - /// @dev Deprecated rebate pools mapping (no longer used) - mapping(uint256 => uint256) private __DEPRECATED_rebates; // solhint-disable-line var-name-mixedcase - - // -- Slashing -- - - /// @dev List of addresses allowed to slash stakes - mapping(address => bool) internal __slashers; - - // -- Delegation -- - - /// @dev Set the delegation capacity multiplier defined by the delegation ratio - /// If delegation ratio is 100, and an Indexer has staked 5 GRT, - /// then they can use up to 500 GRT from the delegated stake - uint32 internal __delegationRatio; - - /// @dev Time in blocks an indexer needs to wait to change delegation parameters (deprecated) - uint32 internal __DEPRECATED_delegationParametersCooldown; // solhint-disable-line var-name-mixedcase - - /// @dev Time in epochs a delegator needs to wait to withdraw delegated stake - uint32 internal __delegationUnbondingPeriod; // in epochs - - /// @dev Percentage of tokens to tax a delegation deposit - /// Parts per million. (Allows for 4 decimal points, 999,999 = 99.9999%) - uint32 internal __delegationTaxPercentage; - - /// @dev Delegation pools : indexer => DelegationPool - mapping(address => IStakingData.DelegationPool) internal __delegationPools; - - // -- Operators -- - - /// @dev Operator auth : indexer => operator => is authorized - mapping(address => mapping(address => bool)) internal __operatorAuth; - - // -- Asset Holders -- - - /// @dev DEPRECATED: Allowed AssetHolders: assetHolder => is allowed - mapping(address => bool) private __DEPRECATED_assetHolders; // solhint-disable-line var-name-mixedcase -} - -/** - * @title StakingV2Storage - * @author Edge & Node - * @notice This contract holds all the storage variables for the Staking contract, version 2 - * @dev Note that we use a double underscore prefix for variable names; this prefix identifies - * variables that used to be public but are now internal, getters can be found on StakingExtension.sol. - */ -contract StakingV2Storage is StakingV1Storage { - /// @dev Destination of accrued rewards : beneficiary => rewards destination - mapping(address => address) internal __rewardsDestination; -} - -/** - * @title StakingV3Storage - * @author Edge & Node - * @notice This contract holds all the storage variables for the base Staking contract, version 3. - */ -contract StakingV3Storage is StakingV2Storage { - /// @dev Address of the counterpart Staking contract on L1/L2 - address internal counterpartStakingAddress; - /// @dev Address of the StakingExtension implementation - address internal extensionImpl; -} - -/** - * @title StakingV4Storage - * @author Edge & Node - * @notice This contract holds all the storage variables for the base Staking contract, version 4. - * @dev Note that it includes a storage gap - if adding future versions, make sure to move the gap - * to the new version and reduce the size of the gap accordingly. - */ -contract StakingV4Storage is StakingV3Storage { - /// @dev Numerator for the lambda parameter in exponential rebate calculations - uint32 internal __lambdaNumerator; - /// @dev Denominator for the lambda parameter in exponential rebate calculations - uint32 internal __lambdaDenominator; - - /// @dev Gap to allow adding variables in future upgrades (since L1Staking and L2Staking can have their own storage as well) - uint256[50] private __gap; -} diff --git a/packages/contracts/contracts/staking/libs/Exponential.sol b/packages/contracts/contracts/staking/libs/Exponential.sol deleted file mode 100644 index 2b0222daa..000000000 --- a/packages/contracts/contracts/staking/libs/Exponential.sol +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; - -import { LibFixedMath } from "./LibFixedMath.sol"; - -/** - * @title LibExponential library - * @author Edge & Node - * @notice A library to compute query fee rebates using an exponential formula - */ -library LibExponential { - /// @dev Maximum value of the exponent for which to compute the exponential before clamping to zero. - uint32 private constant MAX_EXPONENT = 15; - - /// @notice The exponential formula used to compute fee-based rewards for - /// staking pools in a given epoch. This function does not perform - /// bounds checking on the inputs, but the following conditions - /// need to be true: - /// 0 <= alphaNumerator / alphaDenominator <= 1 - /// 0 < lambdaNumerator / lambdaDenominator - /// The exponential rebates function has the form: - /// `(1 - alpha * exp ^ (-lambda * stake / fees)) * fees` - /// @param fees Fees generated by indexer in the staking pool. - /// @param stake Stake attributed to the indexer in the staking pool. - /// @param alphaNumerator Numerator of `alpha` in the rebates function. - /// @param alphaDenominator Denominator of `alpha` in the rebates function. - /// @param lambdaNumerator Numerator of `lambda` in the rebates function. - /// @param lambdaDenominator Denominator of `lambda` in the rebates function. - /// @return rewards Rewards owed to the staking pool. - function exponentialRebates( - uint256 fees, - uint256 stake, - uint32 alphaNumerator, - uint32 alphaDenominator, - uint32 lambdaNumerator, - uint32 lambdaDenominator - ) public pure returns (uint256) { - // If alpha is zero indexer gets 100% fees rebate - int256 alpha = LibFixedMath.toFixed(int32(alphaNumerator), int32(alphaDenominator)); - if (alpha == 0) { - return fees; - } - - // No rebates if no fees... - if (fees == 0) { - return 0; - } - - // Award all fees as rebate if the exponent is too large - int256 lambda = LibFixedMath.toFixed(int32(lambdaNumerator), int32(lambdaDenominator)); - int256 exponent = LibFixedMath.mulDiv(lambda, int256(stake), int256(fees)); - if (LibFixedMath.toInteger(exponent) > MAX_EXPONENT) { - return fees; - } - - // Compute `1 - alpha * exp ^(-exponent)` - int256 factor = LibFixedMath.sub(LibFixedMath.one(), LibFixedMath.mul(alpha, LibFixedMath.exp(-exponent))); - - // Weight the fees by the factor - return LibFixedMath.uintMul(factor, fees); - } -} diff --git a/packages/contracts/contracts/staking/libs/LibFixedMath.sol b/packages/contracts/contracts/staking/libs/LibFixedMath.sol deleted file mode 100644 index 55628ea6e..000000000 --- a/packages/contracts/contracts/staking/libs/LibFixedMath.sol +++ /dev/null @@ -1,437 +0,0 @@ -/* - - Copyright 2017 Bprotocol Foundation, 2019 ZeroEx Intl. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -*/ - -// SPDX-License-Identifier: Apache-2.0 - -pragma solidity ^0.7.6; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable function-max-lines, gas-strict-inequalities - -/** - * @title LibFixedMath - * @author Edge & Node - * @notice Signed, fixed-point, 127-bit precision math library - */ -library LibFixedMath { - /// @dev Fixed-point representation of 1 - int256 private constant FIXED_1 = int256(0x0000000000000000000000000000000080000000000000000000000000000000); - /// @dev Minimum fixed-point value (2**255) - int256 private constant MIN_FIXED_VAL = int256(0x8000000000000000000000000000000000000000000000000000000000000000); - /// @dev Fixed-point representation of 1^2 - int256 private constant FIXED_1_SQUARED = - int256(0x4000000000000000000000000000000000000000000000000000000000000000); - /// @dev Maximum value for natural logarithm calculation - int256 private constant LN_MAX_VAL = FIXED_1; - /// @dev Minimum value for natural logarithm calculation (e ^ -63.875) - int256 private constant LN_MIN_VAL = int256(0x0000000000000000000000000000000000000000000000000000000733048c5a); - /// @dev Maximum value for exponentiation calculation - int256 private constant EXP_MAX_VAL = 0; - /// @dev Minimum value for exponentiation calculation (-63.875) - int256 private constant EXP_MIN_VAL = -int256(0x0000000000000000000000000000001ff0000000000000000000000000000000); - - /// @notice Get one as a fixed-point number. - /// @return f The fixed-point representation of 1 - function one() internal pure returns (int256 f) { - f = FIXED_1; - } - - /// @notice Returns the addition of two fixed point numbers, reverting on overflow. - /// @param a First fixed-point number - /// @param b Second fixed-point number - /// @return c The sum of a and b - function add(int256 a, int256 b) internal pure returns (int256 c) { - c = _add(a, b); - } - - /// @notice Returns the subtraction of two fixed point numbers, reverting on overflow. - /// @param a First fixed-point number - /// @param b Second fixed-point number - /// @return c The difference a - b - function sub(int256 a, int256 b) internal pure returns (int256 c) { - if (b == MIN_FIXED_VAL) { - revert("out-of-bounds"); - } - c = _add(a, -b); - } - - /// @notice Returns the multiplication of two fixed point numbers, reverting on overflow. - /// @param a First fixed-point number - /// @param b Second fixed-point number - /// @return c The product of a and b - function mul(int256 a, int256 b) internal pure returns (int256 c) { - c = _mul(a, b) / FIXED_1; - } - - /// @notice Returns the division of two fixed point numbers. - /// @param a Dividend fixed-point number - /// @param b Divisor fixed-point number - /// @return c The quotient a / b - function div(int256 a, int256 b) internal pure returns (int256 c) { - c = _div(_mul(a, FIXED_1), b); - } - - /// @notice Performs (a * n) / d, without scaling for precision. - /// @param a First operand - /// @param n Numerator - /// @param d Denominator - /// @return c The result of (a * n) / d - function mulDiv(int256 a, int256 n, int256 d) internal pure returns (int256 c) { - c = _div(_mul(a, n), d); - } - - /// @notice Returns the unsigned integer result of multiplying a fixed-point - /// number with an integer, reverting if the multiplication overflows. - /// Negative results are clamped to zero. - /// @param f Fixed-point number - /// @param u Unsigned integer - /// @return The result of f * u as an unsigned integer - function uintMul(int256 f, uint256 u) internal pure returns (uint256) { - if (int256(u) < int256(0)) { - revert("out-of-bounds"); - } - int256 c = _mul(f, int256(u)); - if (c <= 0) { - return 0; - } - return uint256(uint256(c) >> 127); - } - - /// @notice Returns the absolute value of a fixed point number. - /// @param f Fixed-point number - /// @return c The absolute value of f - function abs(int256 f) internal pure returns (int256 c) { - if (f == MIN_FIXED_VAL) { - revert("out-of-bounds"); - } - if (f >= 0) { - c = f; - } else { - c = -f; - } - } - - /// @notice Returns 1 / `x`, where `x` is a fixed-point number. - /// @param f Fixed-point number to invert - /// @return c The reciprocal of f - function invert(int256 f) internal pure returns (int256 c) { - c = _div(FIXED_1_SQUARED, f); - } - - /// @notice Convert signed `n` / 1 to a fixed-point number. - /// @param n Signed integer to convert - /// @return f The fixed-point representation of n - function toFixed(int256 n) internal pure returns (int256 f) { - f = _mul(n, FIXED_1); - } - - /// @notice Convert signed `n` / `d` to a fixed-point number. - /// @param n Numerator - /// @param d Denominator - /// @return f The fixed-point representation of n/d - function toFixed(int256 n, int256 d) internal pure returns (int256 f) { - f = _div(_mul(n, FIXED_1), d); - } - - /// @notice Convert unsigned `n` / 1 to a fixed-point number. - /// Reverts if `n` is too large to fit in a fixed-point number. - /// @param n Unsigned integer to convert - /// @return f The fixed-point representation of n - function toFixed(uint256 n) internal pure returns (int256 f) { - if (int256(n) < int256(0)) { - revert("out-of-bounds"); - } - f = _mul(int256(n), FIXED_1); - } - - /// @notice Convert unsigned `n` / `d` to a fixed-point number. - /// Reverts if `n` / `d` is too large to fit in a fixed-point number. - /// @param n Numerator - /// @param d Denominator - /// @return f The fixed-point representation of n/d - function toFixed(uint256 n, uint256 d) internal pure returns (int256 f) { - if (int256(n) < int256(0)) { - revert("out-of-bounds"); - } - if (int256(d) < int256(0)) { - revert("out-of-bounds"); - } - f = _div(_mul(int256(n), FIXED_1), int256(d)); - } - - /// @notice Convert a fixed-point number to an integer. - /// @param f Fixed-point number to convert - /// @return n The integer representation of f - function toInteger(int256 f) internal pure returns (int256 n) { - return f / FIXED_1; - } - - /// @notice Get the natural logarithm of a fixed-point number 0 < `x` <= LN_MAX_VAL - /// @param x Fixed-point number to compute logarithm of - /// @return r The natural logarithm of x - function ln(int256 x) internal pure returns (int256 r) { - if (x > LN_MAX_VAL) { - revert("out-of-bounds"); - } - if (x <= 0) { - revert("too-small"); - } - if (x == FIXED_1) { - return 0; - } - if (x <= LN_MIN_VAL) { - return EXP_MIN_VAL; - } - - int256 y; - int256 z; - int256 w; - - // Rewrite the input as a quotient of negative natural exponents and a single residual q, such that 1 < q < 2 - // For example: log(0.3) = log(e^-1 * e^-0.25 * 1.0471028872385522) - // = 1 - 0.25 - log(1 + 0.0471028872385522) - // e ^ -32 - if (x <= int256(0x00000000000000000000000000000000000000000001c8464f76164760000000)) { - r -= int256(0x0000000000000000000000000000001000000000000000000000000000000000); // - 32 - x = (x * FIXED_1) / int256(0x00000000000000000000000000000000000000000001c8464f76164760000000); // / e ^ -32 - } - // e ^ -16 - if (x <= int256(0x00000000000000000000000000000000000000f1aaddd7742e90000000000000)) { - r -= int256(0x0000000000000000000000000000000800000000000000000000000000000000); // - 16 - x = (x * FIXED_1) / int256(0x00000000000000000000000000000000000000f1aaddd7742e90000000000000); // / e ^ -16 - } - // e ^ -8 - if (x <= int256(0x00000000000000000000000000000000000afe10820813d78000000000000000)) { - r -= int256(0x0000000000000000000000000000000400000000000000000000000000000000); // - 8 - x = (x * FIXED_1) / int256(0x00000000000000000000000000000000000afe10820813d78000000000000000); // / e ^ -8 - } - // e ^ -4 - if (x <= int256(0x0000000000000000000000000000000002582ab704279ec00000000000000000)) { - r -= int256(0x0000000000000000000000000000000200000000000000000000000000000000); // - 4 - x = (x * FIXED_1) / int256(0x0000000000000000000000000000000002582ab704279ec00000000000000000); // / e ^ -4 - } - // e ^ -2 - if (x <= int256(0x000000000000000000000000000000001152aaa3bf81cc000000000000000000)) { - r -= int256(0x0000000000000000000000000000000100000000000000000000000000000000); // - 2 - x = (x * FIXED_1) / int256(0x000000000000000000000000000000001152aaa3bf81cc000000000000000000); // / e ^ -2 - } - // e ^ -1 - if (x <= int256(0x000000000000000000000000000000002f16ac6c59de70000000000000000000)) { - r -= int256(0x0000000000000000000000000000000080000000000000000000000000000000); // - 1 - x = (x * FIXED_1) / int256(0x000000000000000000000000000000002f16ac6c59de70000000000000000000); // / e ^ -1 - } - // e ^ -0.5 - if (x <= int256(0x000000000000000000000000000000004da2cbf1be5828000000000000000000)) { - r -= int256(0x0000000000000000000000000000000040000000000000000000000000000000); // - 0.5 - x = (x * FIXED_1) / int256(0x000000000000000000000000000000004da2cbf1be5828000000000000000000); // / e ^ -0.5 - } - // e ^ -0.25 - if (x <= int256(0x0000000000000000000000000000000063afbe7ab2082c000000000000000000)) { - r -= int256(0x0000000000000000000000000000000020000000000000000000000000000000); // - 0.25 - x = (x * FIXED_1) / int256(0x0000000000000000000000000000000063afbe7ab2082c000000000000000000); // / e ^ -0.25 - } - // e ^ -0.125 - if (x <= int256(0x0000000000000000000000000000000070f5a893b608861e1f58934f97aea57d)) { - r -= int256(0x0000000000000000000000000000000010000000000000000000000000000000); // - 0.125 - x = (x * FIXED_1) / int256(0x0000000000000000000000000000000070f5a893b608861e1f58934f97aea57d); // / e ^ -0.125 - } - // `x` is now our residual in the range of 1 <= x <= 2 (or close enough). - - // Add the taylor series for log(1 + z), where z = x - 1 - z = y = x - FIXED_1; - w = (y * y) / FIXED_1; - r += (z * (0x100000000000000000000000000000000 - y)) / 0x100000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^01 / 01 - y^02 / 02 - r += (z * (0x0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa - y)) / 0x200000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^03 / 03 - y^04 / 04 - r += (z * (0x099999999999999999999999999999999 - y)) / 0x300000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^05 / 05 - y^06 / 06 - r += (z * (0x092492492492492492492492492492492 - y)) / 0x400000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^07 / 07 - y^08 / 08 - r += (z * (0x08e38e38e38e38e38e38e38e38e38e38e - y)) / 0x500000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^09 / 09 - y^10 / 10 - r += (z * (0x08ba2e8ba2e8ba2e8ba2e8ba2e8ba2e8b - y)) / 0x600000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^11 / 11 - y^12 / 12 - r += (z * (0x089d89d89d89d89d89d89d89d89d89d89 - y)) / 0x700000000000000000000000000000000; - z = (z * w) / FIXED_1; // add y^13 / 13 - y^14 / 14 - r += (z * (0x088888888888888888888888888888888 - y)) / 0x800000000000000000000000000000000; // add y^15 / 15 - y^16 / 16 - } - - /// @notice Compute the natural exponent for a fixed-point number EXP_MIN_VAL <= `x` <= 1 - /// @param x Fixed-point number to compute exponent of - /// @return r The natural exponent of x - function exp(int256 x) internal pure returns (int256 r) { - if (x < EXP_MIN_VAL) { - // Saturate to zero below EXP_MIN_VAL. - return 0; - } - if (x == 0) { - return FIXED_1; - } - if (x > EXP_MAX_VAL) { - revert("out-of-bounds"); - } - - // Rewrite the input as a product of natural exponents and a - // single residual q, where q is a number of small magnitude. - // For example: e^-34.419 = e^(-32 - 2 - 0.25 - 0.125 - 0.044) - // = e^-32 * e^-2 * e^-0.25 * e^-0.125 * e^-0.044 - // -> q = -0.044 - - // Multiply with the taylor series for e^q - int256 y; - int256 z; - // q = x % 0.125 (the residual) - z = y = x % 0x0000000000000000000000000000000010000000000000000000000000000000; - z = (z * y) / FIXED_1; - r += z * 0x10e1b3be415a0000; // add y^02 * (20! / 02!) - z = (z * y) / FIXED_1; - r += z * 0x05a0913f6b1e0000; // add y^03 * (20! / 03!) - z = (z * y) / FIXED_1; - r += z * 0x0168244fdac78000; // add y^04 * (20! / 04!) - z = (z * y) / FIXED_1; - r += z * 0x004807432bc18000; // add y^05 * (20! / 05!) - z = (z * y) / FIXED_1; - r += z * 0x000c0135dca04000; // add y^06 * (20! / 06!) - z = (z * y) / FIXED_1; - r += z * 0x0001b707b1cdc000; // add y^07 * (20! / 07!) - z = (z * y) / FIXED_1; - r += z * 0x000036e0f639b800; // add y^08 * (20! / 08!) - z = (z * y) / FIXED_1; - r += z * 0x00000618fee9f800; // add y^09 * (20! / 09!) - z = (z * y) / FIXED_1; - r += z * 0x0000009c197dcc00; // add y^10 * (20! / 10!) - z = (z * y) / FIXED_1; - r += z * 0x0000000e30dce400; // add y^11 * (20! / 11!) - z = (z * y) / FIXED_1; - r += z * 0x000000012ebd1300; // add y^12 * (20! / 12!) - z = (z * y) / FIXED_1; - r += z * 0x0000000017499f00; // add y^13 * (20! / 13!) - z = (z * y) / FIXED_1; - r += z * 0x0000000001a9d480; // add y^14 * (20! / 14!) - z = (z * y) / FIXED_1; - r += z * 0x00000000001c6380; // add y^15 * (20! / 15!) - z = (z * y) / FIXED_1; - r += z * 0x000000000001c638; // add y^16 * (20! / 16!) - z = (z * y) / FIXED_1; - r += z * 0x0000000000001ab8; // add y^17 * (20! / 17!) - z = (z * y) / FIXED_1; - r += z * 0x000000000000017c; // add y^18 * (20! / 18!) - z = (z * y) / FIXED_1; - r += z * 0x0000000000000014; // add y^19 * (20! / 19!) - z = (z * y) / FIXED_1; - r += z * 0x0000000000000001; // add y^20 * (20! / 20!) - r = r / 0x21c3677c82b40000 + y + FIXED_1; // divide by 20! and then add y^1 / 1! + y^0 / 0! - - // Multiply with the non-residual terms. - x = -x; - // e ^ -32 - if ((x & int256(0x0000000000000000000000000000001000000000000000000000000000000000)) != 0) { - r = - (r * int256(0x00000000000000000000000000000000000000f1aaddd7742e56d32fb9f99744)) / - int256(0x0000000000000000000000000043cbaf42a000812488fc5c220ad7b97bf6e99e); // * e ^ -32 - } - // e ^ -16 - if ((x & int256(0x0000000000000000000000000000000800000000000000000000000000000000)) != 0) { - r = - (r * int256(0x00000000000000000000000000000000000afe10820813d65dfe6a33c07f738f)) / - int256(0x000000000000000000000000000005d27a9f51c31b7c2f8038212a0574779991); // * e ^ -16 - } - // e ^ -8 - if ((x & int256(0x0000000000000000000000000000000400000000000000000000000000000000)) != 0) { - r = - (r * int256(0x0000000000000000000000000000000002582ab704279e8efd15e0265855c47a)) / - int256(0x0000000000000000000000000000001b4c902e273a58678d6d3bfdb93db96d02); // * e ^ -8 - } - // e ^ -4 - if ((x & int256(0x0000000000000000000000000000000200000000000000000000000000000000)) != 0) { - r = - (r * int256(0x000000000000000000000000000000001152aaa3bf81cb9fdb76eae12d029571)) / - int256(0x00000000000000000000000000000003b1cc971a9bb5b9867477440d6d157750); // * e ^ -4 - } - // e ^ -2 - if ((x & int256(0x0000000000000000000000000000000100000000000000000000000000000000)) != 0) { - r = - (r * int256(0x000000000000000000000000000000002f16ac6c59de6f8d5d6f63c1482a7c86)) / - int256(0x000000000000000000000000000000015bf0a8b1457695355fb8ac404e7a79e3); // * e ^ -2 - } - // e ^ -1 - if ((x & int256(0x0000000000000000000000000000000080000000000000000000000000000000)) != 0) { - r = - (r * int256(0x000000000000000000000000000000004da2cbf1be5827f9eb3ad1aa9866ebb3)) / - int256(0x00000000000000000000000000000000d3094c70f034de4b96ff7d5b6f99fcd8); // * e ^ -1 - } - // e ^ -0.5 - if ((x & int256(0x0000000000000000000000000000000040000000000000000000000000000000)) != 0) { - r = - (r * int256(0x0000000000000000000000000000000063afbe7ab2082ba1a0ae5e4eb1b479dc)) / - int256(0x00000000000000000000000000000000a45af1e1f40c333b3de1db4dd55f29a7); // * e ^ -0.5 - } - // e ^ -0.25 - if ((x & int256(0x0000000000000000000000000000000020000000000000000000000000000000)) != 0) { - r = - (r * int256(0x0000000000000000000000000000000070f5a893b608861e1f58934f97aea57d)) / - int256(0x00000000000000000000000000000000910b022db7ae67ce76b441c27035c6a1); // * e ^ -0.25 - } - // e ^ -0.125 - if ((x & int256(0x0000000000000000000000000000000010000000000000000000000000000000)) != 0) { - r = - (r * int256(0x00000000000000000000000000000000783eafef1c0a8f3978c7f81824d62ebf)) / - int256(0x0000000000000000000000000000000088415abbe9a76bead8d00cf112e4d4a8); // * e ^ -0.125 - } - } - - /// @notice Returns the multiplication two numbers, reverting on overflow. - /// @param a First operand - /// @param b Second operand - /// @return c The product of a and b - function _mul(int256 a, int256 b) private pure returns (int256 c) { - if (a == 0 || b == 0) { - return 0; - } - c = a * b; - if (c / a != b || c / b != a) { - revert("overflow"); - } - } - - /// @notice Returns the division of two numbers, reverting on division by zero. - /// @param a Dividend - /// @param b Divisor - /// @return c The quotient of a and b - function _div(int256 a, int256 b) private pure returns (int256 c) { - if (b == 0) { - revert("overflow"); - } - if (a == MIN_FIXED_VAL && b == -1) { - revert("overflow"); - } - c = a / b; - } - - /// @notice Adds two numbers, reverting on overflow. - /// @param a First operand - /// @param b Second operand - /// @return c The sum of a and b - function _add(int256 a, int256 b) private pure returns (int256 c) { - c = a + b; - if ((a < 0 && b < 0 && c > a) || (a > 0 && b > 0 && c < a)) { - revert("overflow"); - } - } -} diff --git a/packages/contracts/contracts/staking/libs/Stakes.sol b/packages/contracts/contracts/staking/libs/Stakes.sol deleted file mode 100644 index 459a82996..000000000 --- a/packages/contracts/contracts/staking/libs/Stakes.sol +++ /dev/null @@ -1,187 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -import { SafeMath } from "@openzeppelin/contracts/math/SafeMath.sol"; - -import { MathUtils } from "./MathUtils.sol"; -import { IStakes } from "@graphprotocol/interfaces/contracts/contracts/staking/libs/IStakes.sol"; - -/** - * @title A collection of data structures and functions to manage the Indexer Stake state. - * @author Edge & Node - * @notice A collection of data structures and functions to manage the Indexer Stake state. - * Used for low-level state changes, require() conditions should be evaluated - * at the caller function scope. - */ -library Stakes { - using SafeMath for uint256; - using Stakes for IStakes.Indexer; - - /** - * @notice Deposit tokens to the indexer stake. - * @param stake Stake data - * @param _tokens Amount of tokens to deposit - */ - function deposit(IStakes.Indexer storage stake, uint256 _tokens) internal { - stake.tokensStaked = stake.tokensStaked.add(_tokens); - } - - /** - * @notice Release tokens from the indexer stake. - * @param stake Stake data - * @param _tokens Amount of tokens to release - */ - function release(IStakes.Indexer storage stake, uint256 _tokens) internal { - stake.tokensStaked = stake.tokensStaked.sub(_tokens); - } - - /** - * @notice Allocate tokens from the main stack to a SubgraphDeployment. - * @param stake Stake data - * @param _tokens Amount of tokens to allocate - */ - function allocate(IStakes.Indexer storage stake, uint256 _tokens) internal { - stake.tokensAllocated = stake.tokensAllocated.add(_tokens); - } - - /** - * @notice Unallocate tokens from a SubgraphDeployment back to the main stack. - * @param stake Stake data - * @param _tokens Amount of tokens to unallocate - */ - function unallocate(IStakes.Indexer storage stake, uint256 _tokens) internal { - stake.tokensAllocated = stake.tokensAllocated.sub(_tokens); - } - - /** - * @notice Lock tokens until a thawing period pass. - * @param stake Stake data - * @param _tokens Amount of tokens to unstake - * @param _period Period in blocks that need to pass before withdrawal - */ - function lockTokens(IStakes.Indexer storage stake, uint256 _tokens, uint256 _period) internal { - // Take into account period averaging for multiple unstake requests - uint256 lockingPeriod = _period; - if (stake.tokensLocked > 0) { - lockingPeriod = MathUtils.weightedAverageRoundingUp( - MathUtils.diffOrZero(stake.tokensLockedUntil, block.number), // Remaining thawing period - stake.tokensLocked, // Weighted by remaining unstaked tokens - _period, // Thawing period - _tokens // Weighted by new tokens to unstake - ); - } - - // Update balances - stake.tokensLocked = stake.tokensLocked.add(_tokens); - stake.tokensLockedUntil = block.number.add(lockingPeriod); - } - - /** - * @notice Unlock tokens. - * @param stake Stake data - * @param _tokens Amount of tokens to unlock - */ - function unlockTokens(IStakes.Indexer storage stake, uint256 _tokens) internal { - stake.tokensLocked = stake.tokensLocked.sub(_tokens); - if (stake.tokensLocked == 0) { - stake.tokensLockedUntil = 0; - } - } - - /** - * @notice Take all tokens out from the locked stake for withdrawal. - * @param stake Stake data - * @return Amount of tokens being withdrawn - */ - function withdrawTokens(IStakes.Indexer storage stake) internal returns (uint256) { - // Calculate tokens that can be released - uint256 tokensToWithdraw = stake.tokensWithdrawable(); - - if (tokensToWithdraw > 0) { - // Reset locked tokens - stake.unlockTokens(tokensToWithdraw); - - // Decrease indexer stake - stake.release(tokensToWithdraw); - } - - return tokensToWithdraw; - } - - /** - * @notice Return the amount of tokens used in allocations and locked for withdrawal. - * @param stake Stake data - * @return Token amount - */ - function tokensUsed(IStakes.Indexer memory stake) internal pure returns (uint256) { - return stake.tokensAllocated.add(stake.tokensLocked); - } - - /** - * @notice Return the amount of tokens staked not considering the ones that are already going - * through the thawing period or are ready for withdrawal. We call it secure stake because - * it is not subject to change by a withdraw call from the indexer. - * @param stake Stake data - * @return Token amount - */ - function tokensSecureStake(IStakes.Indexer memory stake) internal pure returns (uint256) { - return stake.tokensStaked.sub(stake.tokensLocked); - } - - /** - * @notice Tokens free balance on the indexer stake that can be used for any purpose. - * Any token that is allocated cannot be used as well as tokens that are going through the - * thawing period or are withdrawable - * Calc: tokensStaked - tokensAllocated - tokensLocked - * @param stake Stake data - * @return Token amount - */ - function tokensAvailable(IStakes.Indexer memory stake) internal pure returns (uint256) { - return stake.tokensAvailableWithDelegation(0); - } - - /** - * @notice Tokens free balance on the indexer stake that can be used for allocations. - * This function accepts a parameter for extra delegated capacity that takes into - * account delegated tokens - * @param stake Stake data - * @param _delegatedCapacity Amount of tokens used from delegators to calculate availability - * @return Token amount - */ - function tokensAvailableWithDelegation( - IStakes.Indexer memory stake, - uint256 _delegatedCapacity - ) internal pure returns (uint256) { - uint256 tokensCapacity = stake.tokensStaked.add(_delegatedCapacity); - uint256 _tokensUsed = stake.tokensUsed(); - // If more tokens are used than the current capacity, the indexer is overallocated. - // This means the indexer doesn't have available capacity to create new allocations. - // We can reach this state when the indexer has funds allocated and then any - // of these conditions happen: - // - The delegationCapacity ratio is reduced. - // - The indexer stake is slashed. - // - A delegator removes enough stake. - if (_tokensUsed > tokensCapacity) { - // Indexer stake is over allocated: return 0 to avoid stake to be used until - // the overallocation is restored by staking more tokens, unallocating tokens - // or using more delegated funds - return 0; - } - return tokensCapacity.sub(_tokensUsed); - } - - /** - * @notice Tokens available for withdrawal after thawing period. - * @param stake Stake data - * @return Token amount - */ - function tokensWithdrawable(IStakes.Indexer memory stake) internal view returns (uint256) { - // No tokens to withdraw before locking period - if (stake.tokensLockedUntil == 0 || block.number < stake.tokensLockedUntil) { - return 0; - } - return stake.tokensLocked; - } -} diff --git a/packages/contracts/contracts/tests/L1GraphTokenLockTransferToolBadMock.sol b/packages/contracts/contracts/tests/L1GraphTokenLockTransferToolBadMock.sol deleted file mode 100644 index 12b06b332..000000000 --- a/packages/contracts/contracts/tests/L1GraphTokenLockTransferToolBadMock.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.7.6; -pragma experimental ABIEncoderV2; - -// solhint-disable named-parameters-mapping -// solhint-disable gas-small-strings - -/** - * @title L1GraphTokenLockTransferToolBadMock - * @author Edge & Node - * @notice Mock contract for testing L1 Graph Token Lock Transfer Tool with bad behavior - */ -contract L1GraphTokenLockTransferToolBadMock { - /** - * @notice Mapping from L1 wallet address to L2 wallet address - */ - mapping(address => address) public l2WalletAddress; - - /** - * @notice Set the L2 wallet address for an L1 wallet - * @param l1Address L1 wallet address - * @param l2Address L2 wallet address - */ - function setL2WalletAddress(address l1Address, address l2Address) external { - l2WalletAddress[l1Address] = l2Address; - } - - /** - * @notice Pull ETH from the contract to the caller (sends 1 wei less than requested for testing) - * @param l1Wallet L1 wallet address to check - * @param amount Amount of ETH to pull - */ - function pullETH(address l1Wallet, uint256 amount) external { - require(l2WalletAddress[l1Wallet] != address(0), "L1GraphTokenLockTransferToolMock: unknown L1 wallet"); - (bool success, ) = payable(msg.sender).call{ value: amount - 1 }(""); - require(success, "L1GraphTokenLockTransferToolMock: ETH pull failed"); - } -} diff --git a/packages/contracts/contracts/tests/L1GraphTokenLockTransferToolMock.sol b/packages/contracts/contracts/tests/L1GraphTokenLockTransferToolMock.sol deleted file mode 100644 index 92e8f73f7..000000000 --- a/packages/contracts/contracts/tests/L1GraphTokenLockTransferToolMock.sol +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-License-Identifier: MIT - -pragma solidity ^0.7.6; -pragma experimental ABIEncoderV2; - -// solhint-disable named-parameters-mapping -// solhint-disable gas-small-strings - -/** - * @title L1GraphTokenLockTransferToolMock - * @author Edge & Node - * @notice Mock contract for testing L1 Graph Token Lock Transfer Tool functionality - */ -contract L1GraphTokenLockTransferToolMock { - /** - * @notice Mapping from L1 wallet address to L2 wallet address - */ - mapping(address => address) public l2WalletAddress; - - /** - * @notice Set the L2 wallet address for an L1 wallet - * @param l1Address L1 wallet address - * @param l2Address L2 wallet address - */ - function setL2WalletAddress(address l1Address, address l2Address) external { - l2WalletAddress[l1Address] = l2Address; - } - - /** - * @notice Pull ETH from the contract to the caller - * @param l1Wallet L1 wallet address to check - * @param amount Amount of ETH to pull - */ - function pullETH(address l1Wallet, uint256 amount) external { - require(l2WalletAddress[l1Wallet] != address(0), "L1GraphTokenLockTransferToolMock: unknown L1 wallet"); - (bool success, ) = payable(msg.sender).call{ value: amount }(""); - require(success, "L1GraphTokenLockTransferToolMock: ETH pull failed"); - } -} diff --git a/packages/contracts/contracts/tests/LegacyGNSMock.sol b/packages/contracts/contracts/tests/LegacyGNSMock.sol deleted file mode 100644 index 30f98ea31..000000000 --- a/packages/contracts/contracts/tests/LegacyGNSMock.sol +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; -pragma abicoder v2; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable use-natspec - -import { L1GNS } from "../discovery/L1GNS.sol"; -import { IGNS } from "@graphprotocol/interfaces/contracts/contracts/discovery/IGNS.sol"; - -/** - * @title LegacyGNSMock contract - * @dev This is used to test the migration of legacy subgraphs to NFT-based subgraphs and transferring them to L2 - */ -contract LegacyGNSMock is L1GNS { - /** - * @notice Create a mock legacy subgraph (owned by the msg.sender) - * @param subgraphNumber Number of the subgraph (sequence ID for the account) - * @param subgraphDeploymentID Subgraph deployment ID - */ - function createLegacySubgraph(uint256 subgraphNumber, bytes32 subgraphDeploymentID) external { - SubgraphData storage subgraphData = legacySubgraphData[msg.sender][subgraphNumber]; - legacySubgraphs[msg.sender][subgraphNumber] = subgraphDeploymentID; - subgraphData.subgraphDeploymentID = subgraphDeploymentID; - subgraphData.nSignal = 1000; // Mock value - } - - /** - * @notice Get the subgraph deployment ID for a subgraph - * @param subgraphID Subgraph ID - * @return subgraphDeploymentID Subgraph deployment ID - */ - function getSubgraphDeploymentID(uint256 subgraphID) external view returns (bytes32 subgraphDeploymentID) { - IGNS.SubgraphData storage subgraph = _getSubgraphData(subgraphID); - subgraphDeploymentID = subgraph.subgraphDeploymentID; - } - - /** - * @notice Get the nSignal for a subgraph - * @param subgraphID Subgraph ID - * @return nSignal The subgraph's nSignal - */ - function getSubgraphNSignal(uint256 subgraphID) external view returns (uint256 nSignal) { - IGNS.SubgraphData storage subgraph = _getSubgraphData(subgraphID); - nSignal = subgraph.nSignal; - } -} diff --git a/packages/contracts/contracts/tests/MockERC165.sol b/packages/contracts/contracts/tests/MockERC165.sol deleted file mode 100644 index 446c752a7..000000000 --- a/packages/contracts/contracts/tests/MockERC165.sol +++ /dev/null @@ -1,20 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; - -import { IERC165 } from "@openzeppelin/contracts/introspection/IERC165.sol"; - -/** - * @title MockERC165 - * @author Edge & Node - * @dev Minimal implementation of IERC165 for testing - * @notice Used to test interface validation - supports only ERC165, not specific interfaces - */ -contract MockERC165 is IERC165 { - /** - * @inheritdoc IERC165 - */ - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { - return interfaceId == type(IERC165).interfaceId; - } -} diff --git a/packages/contracts/contracts/tests/MockIssuanceAllocator.sol b/packages/contracts/contracts/tests/MockIssuanceAllocator.sol deleted file mode 100644 index 24e482a55..000000000 --- a/packages/contracts/contracts/tests/MockIssuanceAllocator.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -// solhint-disable gas-increment-by-one, gas-indexed-events, named-parameters-mapping, use-natspec - -pragma solidity ^0.7.6; -pragma abicoder v2; - -import { IERC165 } from "@openzeppelin/contracts/introspection/IERC165.sol"; -import { TargetIssuancePerBlock } from "@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceAllocatorTypes.sol"; -import { IIssuanceAllocationDistribution } from "@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceAllocationDistribution.sol"; -import { IIssuanceTarget } from "@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceTarget.sol"; - -/** - * @title MockIssuanceAllocator - * @dev A simple mock contract for the IssuanceAllocator interfaces used by RewardsManager. - */ -contract MockIssuanceAllocator is IERC165, IIssuanceAllocationDistribution { - /// @dev Mapping to store TargetIssuancePerBlock for each target - mapping(address => TargetIssuancePerBlock) private _targetIssuance; - - /** - * @dev Call beforeIssuanceAllocationChange on a target - * @param target The target contract address - */ - function callBeforeIssuanceAllocationChange(address target) external { - IIssuanceTarget(target).beforeIssuanceAllocationChange(); - } - - /** - * @inheritdoc IIssuanceAllocationDistribution - */ - function getTargetIssuancePerBlock(address target) external view override returns (TargetIssuancePerBlock memory) { - return _targetIssuance[target]; - } - - /** - * @inheritdoc IIssuanceAllocationDistribution - * @dev Mock always returns current block number - */ - function distributeIssuance() external view override returns (uint256) { - return block.number; - } - - /** - * @dev Set target issuance directly for testing - * @param target The target contract address - * @param allocatorIssuance The allocator issuance per block - * @param selfIssuance The self issuance per block - * @param callBefore Whether to call beforeIssuanceAllocationChange on the target - */ - function setTargetAllocation( - address target, - uint256 allocatorIssuance, - uint256 selfIssuance, - bool callBefore - ) external { - if (callBefore) { - IIssuanceTarget(target).beforeIssuanceAllocationChange(); - } - _targetIssuance[target] = TargetIssuancePerBlock({ - allocatorIssuanceRate: allocatorIssuance, - allocatorIssuanceBlockAppliedTo: block.number, - selfIssuanceRate: selfIssuance, - selfIssuanceBlockAppliedTo: block.number - }); - } - - /** - * @inheritdoc IERC165 - */ - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { - return - interfaceId == type(IIssuanceAllocationDistribution).interfaceId || - interfaceId == type(IERC165).interfaceId; - } -} diff --git a/packages/contracts/contracts/tests/MockRewardsEligibilityOracle.sol b/packages/contracts/contracts/tests/MockRewardsEligibilityOracle.sol deleted file mode 100644 index b0ac05a19..000000000 --- a/packages/contracts/contracts/tests/MockRewardsEligibilityOracle.sol +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -// solhint-disable named-parameters-mapping - -pragma solidity ^0.7.6; - -import { IProviderEligibility } from "@graphprotocol/interfaces/contracts/issuance/eligibility/IProviderEligibility.sol"; -import { IERC165 } from "@openzeppelin/contracts/introspection/IERC165.sol"; - -/** - * @title MockRewardsEligibilityOracle - * @author Edge & Node - * @notice A simple mock contract for the RewardsEligibilityOracle interface - * @dev A simple mock contract for the RewardsEligibilityOracle interface - */ -contract MockRewardsEligibilityOracle is IProviderEligibility, IERC165 { - /// @dev Mapping to store eligibility status for each indexer - mapping(address => bool) private eligible; - - /// @dev Mapping to track which indexers have been explicitly set - mapping(address => bool) private isSet; - - /// @dev Default response for indexers not explicitly set - bool private defaultResponse; - - /** - * @notice Constructor - * @param newDefaultResponse Default response for isEligible - */ - constructor(bool newDefaultResponse) { - defaultResponse = newDefaultResponse; - } - - /** - * @notice Set whether a specific indexer is eligible - * @param indexer The indexer address - * @param eligibility Whether the indexer is eligible - */ - function setIndexerEligible(address indexer, bool eligibility) external { - eligible[indexer] = eligibility; - isSet[indexer] = true; - } - - /** - * @notice Set the default response for indexers not explicitly set - * @param newDefaultResponse The default response - */ - function setDefaultResponse(bool newDefaultResponse) external { - defaultResponse = newDefaultResponse; - } - - /** - * @inheritdoc IProviderEligibility - */ - function isEligible(address indexer) external view override returns (bool) { - // If the indexer has been explicitly set, return that value - if (isSet[indexer]) { - return eligible[indexer]; - } - - // Otherwise return the default response - return defaultResponse; - } - - /** - * @inheritdoc IERC165 - */ - function supportsInterface(bytes4 interfaceId) public pure override returns (bool) { - return interfaceId == type(IProviderEligibility).interfaceId || interfaceId == type(IERC165).interfaceId; - } -} diff --git a/packages/contracts/contracts/tests/MockSubgraphService.sol b/packages/contracts/contracts/tests/MockSubgraphService.sol deleted file mode 100644 index 1e355923b..000000000 --- a/packages/contracts/contracts/tests/MockSubgraphService.sol +++ /dev/null @@ -1,126 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -// solhint-disable named-parameters-mapping - -pragma solidity ^0.7.6; - -import { IRewardsIssuer } from "@graphprotocol/interfaces/contracts/contracts/rewards/IRewardsIssuer.sol"; - -/** - * @title MockSubgraphService - * @author Edge & Node - * @notice A mock contract for testing SubgraphService as a rewards issuer - * @dev Implements IRewardsIssuer interface to simulate SubgraphService behavior in tests - */ -contract MockSubgraphService is IRewardsIssuer { - /// @dev Struct to store allocation data - struct Allocation { - bool isActive; - address indexer; - bytes32 subgraphDeploymentId; - uint256 tokens; - uint256 accRewardsPerAllocatedToken; - uint256 accRewardsPending; - } - - /// @dev Mapping of allocation ID to allocation data - mapping(address => Allocation) private allocations; - - /// @dev Mapping of subgraph deployment ID to total allocated tokens - mapping(bytes32 => uint256) private subgraphAllocatedTokens; - - /** - * @notice Set allocation data for testing - * @param allocationId The allocation ID - * @param isActive Whether the allocation is active - * @param indexer The indexer address - * @param subgraphDeploymentId The subgraph deployment ID - * @param tokens Amount of allocated tokens - * @param accRewardsPerAllocatedToken Rewards snapshot - * @param accRewardsPending Accumulated rewards pending - */ - function setAllocation( - address allocationId, - bool isActive, - address indexer, - bytes32 subgraphDeploymentId, - uint256 tokens, - uint256 accRewardsPerAllocatedToken, - uint256 accRewardsPending - ) external { - allocations[allocationId] = Allocation({ - isActive: isActive, - indexer: indexer, - subgraphDeploymentId: subgraphDeploymentId, - tokens: tokens, - accRewardsPerAllocatedToken: accRewardsPerAllocatedToken, - accRewardsPending: accRewardsPending - }); - } - - /** - * @notice Set total allocated tokens for a subgraph - * @param subgraphDeploymentId The subgraph deployment ID - * @param tokens Total tokens allocated - */ - function setSubgraphAllocatedTokens(bytes32 subgraphDeploymentId, uint256 tokens) external { - subgraphAllocatedTokens[subgraphDeploymentId] = tokens; - } - - /** - * @inheritdoc IRewardsIssuer - */ - function getAllocationData( - address allocationId - ) - external - view - override - returns ( - bool isActive, - address indexer, - bytes32 subgraphDeploymentId, - uint256 tokens, - uint256 accRewardsPerAllocatedToken, - uint256 accRewardsPending - ) - { - Allocation memory allocation = allocations[allocationId]; - return ( - allocation.isActive, - allocation.indexer, - allocation.subgraphDeploymentId, - allocation.tokens, - allocation.accRewardsPerAllocatedToken, - allocation.accRewardsPending - ); - } - - /** - * @inheritdoc IRewardsIssuer - */ - function getSubgraphAllocatedTokens(bytes32 subgraphDeploymentId) external view override returns (uint256) { - return subgraphAllocatedTokens[subgraphDeploymentId]; - } - - /** - * @notice Helper function to call reclaimRewards on RewardsManager for testing - * @param rewardsManager Address of the RewardsManager contract - * @param reason Reason identifier for reclaiming rewards - * @param allocationId The allocation ID - * @return Amount of rewards reclaimed - */ - function callReclaimRewards( - address rewardsManager, - bytes32 reason, - address allocationId - ) external returns (uint256) { - // Call reclaimRewards on the RewardsManager - // solhint-disable-next-line avoid-low-level-calls - (bool success, bytes memory data) = rewardsManager.call( - abi.encodeWithSignature("reclaimRewards(bytes32,address)", reason, allocationId) - ); - require(success, "reclaimRewards call failed"); - return abi.decode(data, (uint256)); - } -} diff --git a/packages/contracts/contracts/tests/arbitrum/ArbSysMock.sol b/packages/contracts/contracts/tests/arbitrum/ArbSysMock.sol deleted file mode 100644 index 3c256fa74..000000000 --- a/packages/contracts/contracts/tests/arbitrum/ArbSysMock.sol +++ /dev/null @@ -1,34 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; - -// TODO: Re-enable and fix issues when publishing a new version -// solhint-disable use-natspec - -/** - * @title ArbSys Mock Contract - * @dev This is a mock implementation of the ArbSys precompiled contract used in Arbitrum - * It's used for testing the L2GraphTokenGateway contract - */ -contract ArbSysMock { - /** - * @dev Emitted when a transaction is sent from L2 to L1 - * @param from Address sending the transaction on L2 - * @param to Address receiving the transaction on L1 - * @param id Unique identifier for the L2-to-L1 transaction - * @param data Transaction data - */ - event L2ToL1Tx(address indexed from, address indexed to, uint256 indexed id, bytes data); - - /** - * @notice Send a transaction to L1 - * @param destination The address on L1 to send the transaction to - * @param calldataForL1 The calldata for the transaction - * @return A unique identifier for this L2-to-L1 transaction - */ - function sendTxToL1(address destination, bytes calldata calldataForL1) external returns (uint256) { - uint256 id = 1; // Always return 1 for testing - emit L2ToL1Tx(msg.sender, destination, id, calldataForL1); - return id; - } -} diff --git a/packages/contracts/contracts/tests/ens/IENS.sol b/packages/contracts/contracts/tests/ens/IENS.sol deleted file mode 100644 index 042a9170f..000000000 --- a/packages/contracts/contracts/tests/ens/IENS.sol +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; - -// Needed for abi and typechain in the npm package -/** - * @title ENS Registry Interface - * @author Edge & Node - * @notice Interface for the Ethereum Name Service registry - */ -interface IENS { - /** - * @notice Get the owner of a node - * @param node The node to query - * @return The address of the owner - */ - function owner(bytes32 node) external view returns (address); - - /** - * @notice Set the record for a subnode - * @dev Must call setRecord, not setOwner. We must namehash it ourselves as well. - * @param node The parent node - * @param label The label hash of the subnode - * @param _owner The address of the new owner - * @param resolver The address of the resolver - * @param ttl The TTL in seconds - */ - function setSubnodeRecord(bytes32 node, bytes32 label, address _owner, address resolver, uint64 ttl) external; -} diff --git a/packages/contracts/contracts/tests/ens/IPublicResolver.sol b/packages/contracts/contracts/tests/ens/IPublicResolver.sol deleted file mode 100644 index 7a449fb8d..000000000 --- a/packages/contracts/contracts/tests/ens/IPublicResolver.sol +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; - -// Needed for abi and typechain in the npm package -/** - * @title ENS Public Resolver Interface - * @author Edge & Node - * @notice Interface for the ENS public resolver contract - */ -interface IPublicResolver { - /** - * @notice Get the text record for a node - * @param node The node to query - * @param key The key of the text record - * @return The text record value - */ - function text(bytes32 node, string calldata key) external view returns (string memory); - - /** - * @notice Set the text record for a node - * @param node The node to set the record for - * @param key The key of the text record - * @param value The value to set - */ - function setText(bytes32 node, string calldata key, string calldata value) external; -} diff --git a/packages/contracts/contracts/tests/ens/ITestRegistrar.sol b/packages/contracts/contracts/tests/ens/ITestRegistrar.sol deleted file mode 100644 index 406a27fb7..000000000 --- a/packages/contracts/contracts/tests/ens/ITestRegistrar.sol +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -pragma solidity ^0.7.6; - -/** - * @title Test Registrar Interface - * @author Edge & Node - * @notice Interface for a test ENS registrar contract - */ -interface ITestRegistrar { - /** - * @notice Register a name with the registrar - * @param label The label hash to register - * @param owner The address to assign ownership to - */ - function register(bytes32 label, address owner) external; -} diff --git a/packages/contracts/hardhat.config.ts b/packages/contracts/hardhat.config.ts index 53541e927..305b3b58f 100644 --- a/packages/contracts/hardhat.config.ts +++ b/packages/contracts/hardhat.config.ts @@ -83,9 +83,6 @@ const config: HardhatUserConfig = { '@openzeppelin/contracts/**/*': { default: 'off', }, - 'contracts/staking/StakingExtension.sol': { - 5667: 'off', // Unused function parameter - }, }, } diff --git a/packages/contracts/index.d.ts b/packages/contracts/index.d.ts index f31d00d5c..b37262fbc 100644 --- a/packages/contracts/index.d.ts +++ b/packages/contracts/index.d.ts @@ -3,7 +3,6 @@ export * from './types' // Export runtime values export const addressBookDir: string -export const configDir: string export const artifactsDir: string // Keep the original IPFS declaration diff --git a/packages/contracts/index.js b/packages/contracts/index.js index 8b83c20f1..a312735cb 100644 --- a/packages/contracts/index.js +++ b/packages/contracts/index.js @@ -6,8 +6,6 @@ const path = require('path') module.exports = { // Directory where address book files are located addressBookDir: __dirname, - // Directory where config files are located - configDir: path.join(__dirname, 'config'), // Directory where artifacts are located artifactsDir: path.join(__dirname, 'artifacts'), } diff --git a/packages/deployment/test/bytecode-comparison.test.ts b/packages/deployment/test/bytecode-comparison.test.ts index 7ebb90ad1..4cd7be78c 100644 --- a/packages/deployment/test/bytecode-comparison.test.ts +++ b/packages/deployment/test/bytecode-comparison.test.ts @@ -232,13 +232,13 @@ describe('Deploy Implementation Helper', function () { }) it('should load different contracts with correct paths', function () { - const staking = loadContractsArtifact('staking', 'Staking') - expect(staking.abi).to.be.an('array') - expect(staking.bytecode).to.match(/^0x/) + const l2Curation = loadContractsArtifact('l2/curation', 'L2Curation') + expect(l2Curation.abi).to.be.an('array') + expect(l2Curation.bytecode).to.match(/^0x/) - const curation = loadContractsArtifact('curation', 'Curation') - expect(curation.abi).to.be.an('array') - expect(curation.bytecode).to.match(/^0x/) + const l2Token = loadContractsArtifact('l2/token', 'L2GraphToken') + expect(l2Token.abi).to.be.an('array') + expect(l2Token.bytecode).to.match(/^0x/) }) }) }) diff --git a/packages/issuance/test/unit/rewards-manager/mocks/RMEligibilityOracleMock.sol b/packages/issuance/test/unit/rewards-manager/mocks/RMEligibilityOracleMock.sol index 995f627f5..c64efafbf 100644 --- a/packages/issuance/test/unit/rewards-manager/mocks/RMEligibilityOracleMock.sol +++ b/packages/issuance/test/unit/rewards-manager/mocks/RMEligibilityOracleMock.sol @@ -4,7 +4,7 @@ pragma solidity ^0.8.27; import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol"; import { IProviderEligibility } from "@graphprotocol/interfaces/contracts/issuance/eligibility/IProviderEligibility.sol"; -/// 0.8 port of packages/contracts/contracts/tests/MockRewardsEligibilityOracle.sol. +/// Mock for the RewardsManager tests. contract RMEligibilityOracleMock is IProviderEligibility, IERC165 { mapping(address indexer => bool eligibility) private _eligible; mapping(address indexer => bool set) private _isSet; diff --git a/packages/issuance/test/unit/rewards-manager/mocks/RMIssuanceAllocatorMock.sol b/packages/issuance/test/unit/rewards-manager/mocks/RMIssuanceAllocatorMock.sol index ecbb00dbd..2ade749b4 100644 --- a/packages/issuance/test/unit/rewards-manager/mocks/RMIssuanceAllocatorMock.sol +++ b/packages/issuance/test/unit/rewards-manager/mocks/RMIssuanceAllocatorMock.sol @@ -6,7 +6,7 @@ import { TargetIssuancePerBlock } from "@graphprotocol/interfaces/contracts/issu import { IIssuanceAllocationDistribution } from "@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceAllocationDistribution.sol"; import { IIssuanceTarget } from "@graphprotocol/interfaces/contracts/issuance/allocate/IIssuanceTarget.sol"; -/// 0.8 port of packages/contracts/contracts/tests/MockIssuanceAllocator.sol. +/// Mock for the RewardsManager tests. contract RMIssuanceAllocatorMock is IERC165, IIssuanceAllocationDistribution { mapping(address target => TargetIssuancePerBlock issuance) private _targetIssuance; diff --git a/scripts/contracts-migration/manifest.json b/scripts/contracts-migration/manifest.json index bb54725a9..1270b6c16 100644 --- a/scripts/contracts-migration/manifest.json +++ b/scripts/contracts-migration/manifest.json @@ -14,11 +14,6 @@ "SubgraphNFTDescriptor": "packages/contracts/artifacts/contracts/discovery/SubgraphNFTDescriptor.sol/SubgraphNFTDescriptor.json", "EpochManager": "packages/contracts/artifacts/contracts/epochs/EpochManager.sol/EpochManager.json", "RewardsManager": "packages/contracts/artifacts/contracts/rewards/RewardsManager.sol/RewardsManager.json", - "L1GNS": "packages/contracts/artifacts/contracts/discovery/L1GNS.sol/L1GNS.json", - "Curation": "packages/contracts/artifacts/contracts/curation/Curation.sol/Curation.json", - "L1Staking": "packages/contracts/artifacts/contracts/staking/L1Staking.sol/L1Staking.json", - "StakingExtension": "packages/contracts/artifacts/contracts/staking/StakingExtension.sol/StakingExtension.json", - "LibExponential": "packages/contracts/artifacts/contracts/staking/libs/Exponential.sol/LibExponential.json", "HorizonStaking": "packages/horizon/build/contracts/contracts/staking/HorizonStaking.sol/HorizonStaking.json", "GraphPayments": "packages/horizon/build/contracts/contracts/payments/GraphPayments.sol/GraphPayments.json", "PaymentsEscrow": "packages/horizon/build/contracts/contracts/payments/PaymentsEscrow.sol/PaymentsEscrow.json", diff --git a/scripts/contracts-migration/reference.json b/scripts/contracts-migration/reference.json index bba5632c0..173ea0132 100644 --- a/scripts/contracts-migration/reference.json +++ b/scripts/contracts-migration/reference.json @@ -11,10 +11,6 @@ "bytecode": "00e6f46e306ed4b56bee2d3d3dba75404e939d56213f9a1720fb733b3697f4f8", "deployedBytecode": "b31676ab0ab9ae7c5c21a3e29e58d1c05f80994a2462a852df1707e9cec68a3b" }, - "Curation": { - "bytecode": "467680b598f1c37cf0f9ce30ca421168531ec22d4f2e6dea1b230efe5e4f91a3", - "deployedBytecode": "c8b0bdcab52a661ff3a8615f5bf29336615832f4f0b4b3cf4e2506c6b22a87b6" - }, "DisputeManager": { "bytecode": "1c35b2800868b36ed27d6dad5e812ef97cccc05ad1883240ac1b1efb1443d192", "deployedBytecode": "1d2a0f2ae36930e31bab47c7a00e3eec3d6c92320d9d9d89b614f20f2ea2fa34" @@ -47,18 +43,10 @@ "bytecode": "8385b1f97086b46ce0eb3b93d42d5922595bafb8f1eed14588dd3712855ea44d", "deployedBytecode": "6d7255530d2e65918aa05965b6f88051c0f4ae5c69a388b61764cab3fcfd2d80" }, - "L1GNS": { - "bytecode": "1e441ceeaa5098b613b6666e1d0624c3e71425dbb3910b4223595ef9bafe43bc", - "deployedBytecode": "064db8dfa22c6533327307135ef15d5f98e90d462c350a50dd6d9bc75aefe737" - }, "L1GraphTokenGateway": { "bytecode": "25293735575b568a928cf162c13f5bb4ca848833be86a98ad2c4ef7d3970aada", "deployedBytecode": "0b35cd9f9a56eff56b0c97eae2ca8be472cfffecdf83151deae47bda2135bc54" }, - "L1Staking": { - "bytecode": "4b4d19ef9a2a48fc0214593215d24e8f18681951efa9041443d30497c08f718b", - "deployedBytecode": "aeefa8093800d94ff5244470d26851af2b64711bb73a6c8701b59dfb7132377e" - }, "L2Curation": { "bytecode": "8d160a02518b02079b6c6fcdb9be6d356eed976f37adbf40fc9e06db369bd171", "deployedBytecode": "38285a1736db0d3632fb160cdaa0a4d6d9e66d412c6223a6184716caa1f683ec" @@ -75,10 +63,6 @@ "bytecode": "3960ebe0a49a7b2dadb1f866434704f15d1618e8f23f22b24b9791fc5edd172c", "deployedBytecode": "9f500273f04af6e593aba64049e912196f61c912b5ff4a885579b8af6150425d" }, - "LibExponential": { - "bytecode": "cf8e0f70123c2a525e61ab51fcfa8549fd1dc364ffb0f62890504323c3ea1b92", - "deployedBytecode": "d4a129118f42b08e5ed9dd7e29b76fe18767d64ec62e778447a013a25e722ec8" - }, "PaymentsEscrow": { "bytecode": "c5ee87225cd0c023d298d810457736f2a6fcf011d8e9be8bfeea96c4c34936f5", "deployedBytecode": "07e1e1055195ed396e9ac8df7d84d98a37644bea8b48f9ccab0f31f677d53d99" @@ -87,10 +71,6 @@ "bytecode": "0dea68140e59bec61d669269c2097630bd0a9da9b2a241fe887073f741df30ac", "deployedBytecode": "f361c19bcc1553e923fef7a16d423766cf3a0ea2577223f61b84fe41cf1a77da" }, - "StakingExtension": { - "bytecode": "aa3a270946cab805c889d9ef1fd6d3541d8f736fb2ec85b51543836a5c38b23f", - "deployedBytecode": "55758d8712cd9eda9b96bc3922a9d82c8ea3f31be1772d4ea52e9118af611107" - }, "SubgraphNFT": { "bytecode": "830d22ac49214e1f6ba157c5cc7794d69277e96d5c93a773272ab3055a13426a", "deployedBytecode": "9718d61570d90867068568f9b0f33a9633e55bb3cf8e8cea1f11ab5e8298f36a"