Skip to content

Commit 5e7a41f

Browse files
committed
Calculate available rewards using contract instead of events
Rewards are cumulative, so anything that has already been claimed needs to be subtracted to get the current available amount. This commit gets the claimed amount by calling `cumulativeClaimed` on the merkle contract. This is more reliable than scanning for claimed events. Fixes #765
1 parent a6f087e commit 5e7a41f

File tree

5 files changed

+96
-99
lines changed

5 files changed

+96
-99
lines changed

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414
"@ethersproject/constants": "^5.5.0",
1515
"@fontsource/ibm-plex-mono": "^4.5.13",
1616
"@fontsource/inter": "^4.5.10",
17-
"@keep-network/keep-core": "development",
18-
"@keep-network/keep-ecdsa": "development",
19-
"@keep-network/random-beacon": "development",
20-
"@keep-network/tbtc": "development",
17+
"@keep-network/keep-core": "^1.8.1-sepolia.0",
18+
"@keep-network/keep-ecdsa": "^1.9.0-sepolia.0",
19+
"@keep-network/random-beacon": "^2.1.0-sepolia.1",
20+
"@keep-network/tbtc": "^1.1.2-sepolia.0",
2121
"@keep-network/tbtc-v2.ts": "^2.4.1",
2222
"@ledgerhq/connect-kit-loader": "1.1.8",
2323
"@ledgerhq/wallet-api-client": "^1.2.0",
@@ -31,7 +31,7 @@
3131
"@testing-library/react": "^11.1.0",
3232
"@testing-library/user-event": "^12.1.10",
3333
"@threshold-network/components": "development",
34-
"@threshold-network/solidity-contracts": "development",
34+
"@threshold-network/solidity-contracts": "^1.3.0-sepolia.0",
3535
"@types/jest": "^27.0.1",
3636
"@types/node": "^16.9.1",
3737
"@types/numeral": "^2.0.2",

src/hooks/useFetchStakingRewards.ts

Lines changed: 49 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { setInterimRewards } from "../store/rewards"
1212
import { selectStakingProviders } from "../store/staking"
1313
import { BigNumber } from "ethers"
1414
import { Zero } from "@ethersproject/constants"
15+
import { useMulticall } from "../web3/hooks/useMulticall"
16+
import { ContractCall } from "../threshold-ts/multicall"
1517

1618
interface StakingRewards {
1719
[stakingProvider: string]: string
@@ -25,6 +27,16 @@ export const useFetchStakingRewards = () => {
2527
)
2628
const dispatch = useDispatch()
2729

30+
const cumulativeClaimedCalls: ContractCall[] = stakingProviders.map(
31+
(stakingProvider) => ({
32+
address: merkleDropContract!.address,
33+
interface: merkleDropContract!.interface!,
34+
method: "cumulativeClaimed",
35+
args: [stakingProvider],
36+
})
37+
)
38+
const fetchCumulativeClaims = useMulticall(cumulativeClaimedCalls)
39+
2840
useEffect(() => {
2941
const fetch = async () => {
3042
if (
@@ -43,56 +55,48 @@ export const useFetchStakingRewards = () => {
4355
// See https://github.com/threshold-network/token-dashboard/issues/765
4456
// - Note also that TACo rewards now accrue on each block. They can be
4557
// calculated via TACoApp.availableRewards(address _stakingProvider)
46-
const claimedEvents = await getContractPastEvents(merkleDropContract, {
47-
eventName: "Claimed",
48-
fromBlock: DEPLOYMENT_BLOCK,
49-
filterParams: [stakingProviders],
50-
})
5158

52-
const claimedAmountToStakingProvider = claimedEvents.reduce(
53-
(
54-
reducer: { [stakingProvider: string]: string },
55-
event
56-
): { [stakingProvider: string]: string } => {
57-
const stakingProvider = getAddress(
58-
event.args?.stakingProvider as string
59-
)
60-
const prevAmount = BigNumber.from(reducer[stakingProvider] || Zero)
61-
reducer[stakingProvider] = prevAmount
62-
.add(event.args?.amount as string)
63-
.toString()
64-
return reducer
59+
const cumulativeClaimedResults = await fetchCumulativeClaims()
60+
console.log(cumulativeClaimedResults)
61+
62+
const claimedAmountToStakingProvider = stakingProviders.reduce(
63+
(acc, stakingProvider, index) => {
64+
acc[getAddress(stakingProvider)] =
65+
cumulativeClaimedResults[index].toString()
66+
return acc
6567
},
66-
{}
68+
{} as { [stakingProvider: string]: string }
6769
)
70+
console.log(claimedAmountToStakingProvider)
6871

69-
const claimedRewardsInCurrentMerkleRoot = new Set(
70-
claimedEvents
71-
.filter((_) => _.args?.merkleRoot === rewardsData.merkleRoot)
72-
.map((_) => getAddress(_.args?.stakingProvider as string))
73-
)
72+
// const claimedRewardsInCurrentMerkleRoot = new Set(
73+
// claimedEvents
74+
// .filter((_) => _.args?.merkleRoot === rewardsData.merkleRoot)
75+
// .map((_) => getAddress(_.args?.stakingProvider as string))
76+
// )
7477

7578
const stakingRewards: StakingRewards = {}
7679
for (const stakingProvider of stakingProviders) {
77-
if (
78-
!rewardsData.claims.hasOwnProperty(stakingProvider) ||
79-
claimedRewardsInCurrentMerkleRoot.has(stakingProvider)
80-
) {
80+
if (!(stakingProvider in (rewardsData as RewardsJSONData).claims)) {
8181
// If the JSON file doesn't contain proofs for a given staking
82-
// provider it means this staking provider has no Merkle rewards -
83-
// we can skip this iteration.
84-
// TODO: ^ But there's going to be TACo rewards
85-
86-
// If the `Claimed` event exists with a current merkle
87-
// root for a given staking provider it means that rewards have
88-
// already been claimed - we can skip this iteration.
89-
// TODO: ^ Same, there can be TACo rewards
82+
// provider it means this staking provider has no Merkle rewards
9083
continue
9184
}
92-
9385
const { amount } = (rewardsData as RewardsJSONData).claims[
9486
stakingProvider
9587
]
88+
const claimedAmount =
89+
claimedAmountToStakingProvider[stakingProvider] || "0"
90+
if (BigNumber.from(amount).eq(BigNumber.from(claimedAmount))) {
91+
// if the claimed amount is equal to the amount of rewards available, then skip
92+
continue
93+
}
94+
// TODO: ^ But there's going to be TACo rewards
95+
96+
// If the `Claimed` event exists with a current merkle
97+
// root for a given staking provider it means that rewards have
98+
// already been claimed - we can skip this iteration.
99+
// TODO: ^ Same, there can be TACo rewards
96100
const claimableAmount = BigNumber.from(amount).sub(
97101
claimedAmountToStakingProvider[stakingProvider] || Zero
98102
)
@@ -108,5 +112,12 @@ export const useFetchStakingRewards = () => {
108112
}
109113

110114
fetch()
111-
}, [stakingProviders, merkleDropContract, hasFetched, isFetching, dispatch])
115+
}, [
116+
stakingProviders,
117+
merkleDropContract,
118+
hasFetched,
119+
isFetching,
120+
dispatch,
121+
fetchCumulativeClaims,
122+
])
112123
}

src/web3/hooks/useClaimMerkleRewardsTransaction.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export const useClaimMerkleRewardsTransaction = (
3636

3737
// TODO:
3838
// - This only signals no Merkle rewards, but there may be TACo rewards
39-
// - We can still call the new Merkle contract with a claim with an empty
39+
// - We can still call the new Merkle contract with a claim with an empty
4040
// merkle proof, signalling to not try to claim Merkle rewards. This
4141
// will still try to claim TACo rewards automatically.
4242
if (availableRewardsToClaim.length === 0) {

src/web3/hooks/useMerkleDropContract.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ const CONTRACT_ADDRESSESS = {
1212
// https://etherscan.io/address/0xea7ca290c7811d1cc2e79f8d706bd05d8280bd37
1313
[ChainID.Ethereum.valueOf().toString()]:
1414
"0xeA7CA290c7811d1cC2e79f8d706bD05d8280BD37",
15-
// https://sepolia.etherscan.io/address/0x4621a14bbB5a53f79Ea532bdc032b8ACc383B153
15+
// https://sepolia.etherscan.io/address/0xBF807283ef74616065A5595ACa49b25A569A33c6
1616
[ChainID.Sepolia.valueOf().toString()]:
17-
"0x4621a14bbB5a53f79Ea532bdc032b8ACc383B153",
17+
"0xBF807283ef74616065A5595ACa49b25A569A33c6",
1818
// TODO: Set local address- how to resolve it in local network?
1919
[ChainID.Localhost.valueOf().toString()]: AddressZero,
2020
} as Record<string, string>

yarn.lock

Lines changed: 39 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -3327,26 +3327,10 @@
33273327
"@openzeppelin/upgrades" "^2.7.2"
33283328
openzeppelin-solidity "2.4.0"
33293329

3330-
"@keep-network/[email protected]":
3331-
version "1.8.0-dev.5"
3332-
resolved "https://registry.yarnpkg.com/@keep-network/keep-core/-/keep-core-1.8.0-dev.5.tgz#8b4d08ec437f29c94723ee54fcf76456ba5408c3"
3333-
integrity sha512-QVkpO5X28Vczj/xHezV0z2UuMw8QFaR3C8x/d6+3adedsL3nCxgveIGTUcXSuYpBqfx0v4/xT+9bIK7BwLkGPw==
3334-
dependencies:
3335-
"@openzeppelin/upgrades" "^2.7.2"
3336-
openzeppelin-solidity "2.4.0"
3337-
3338-
"@keep-network/[email protected]":
3339-
version "1.8.1-goerli.0"
3340-
resolved "https://registry.yarnpkg.com/@keep-network/keep-core/-/keep-core-1.8.1-goerli.0.tgz#238485aab51902021d42357bf59695225002f0ab"
3341-
integrity sha512-h3La/RqbyEZjBBPg8V+pcRFo3UpWZUF4CxWfXHZnUR4PnkZKnIDrTNFQPhpV2uYFZwrbJxTR9mzOq/DOAiXPwA==
3342-
dependencies:
3343-
"@openzeppelin/upgrades" "^2.7.2"
3344-
openzeppelin-solidity "2.4.0"
3345-
3346-
"@keep-network/keep-core@>1.8.1-dev <1.8.1-goerli", "@keep-network/keep-core@development":
3347-
version "1.8.1-dev.0"
3348-
resolved "https://registry.yarnpkg.com/@keep-network/keep-core/-/keep-core-1.8.1-dev.0.tgz#d95864b25800214de43d8840376a68336cb12055"
3349-
integrity sha512-gFXkgN4PYOYCZ14AskL7fZHEFW5mu3BDd+TJKBuKZc1q9CgRMOK+dxpJnSctxmSH1tV+Ln9v9yqlSkfPCoiBHw==
3330+
"@keep-network/[email protected]", "@keep-network/keep-core@^1.8.1-sepolia.0":
3331+
version "1.8.1-sepolia.0"
3332+
resolved "https://registry.yarnpkg.com/@keep-network/keep-core/-/keep-core-1.8.1-sepolia.0.tgz#62fc477ea0f5c0a44f67eefbdc1219fbe261b4c3"
3333+
integrity sha512-dHdZQR/PWO7Cw8M/GawmsJ5mhaiBOTdd4cUb1DF9fEjUY/4AVrd2F7c39CkrqGCF598ve46hhQWoRLLgtiAv2A==
33503334
dependencies:
33513335
"@openzeppelin/upgrades" "^2.7.2"
33523336
openzeppelin-solidity "2.4.0"
@@ -3361,22 +3345,12 @@
33613345
"@openzeppelin/upgrades" "^2.7.2"
33623346
openzeppelin-solidity "2.3.0"
33633347

3364-
"@keep-network/keep-ecdsa@>1.9.0-dev <1.9.0-ropsten":
3365-
version "1.9.0-goerli.0"
3366-
resolved "https://registry.yarnpkg.com/@keep-network/keep-ecdsa/-/keep-ecdsa-1.9.0-goerli.0.tgz#ce58b6639062bb4f73a257557aebb16447889e08"
3367-
integrity sha512-EA/oTcxmia5nznQ35ub9/5xBqBK4T+78oWYxASCc+THdPLalzriSAtQ517R4QnvkHi82NFhJjZH8WBoRXniddA==
3348+
"@keep-network/[email protected]sepolia.0", "@keep-network/keep-ecdsa@^1.9.0-sepolia.0":
3349+
version "1.9.0-sepolia.0"
3350+
resolved "https://registry.yarnpkg.com/@keep-network/keep-ecdsa/-/keep-ecdsa-1.9.0-sepolia.0.tgz#33d0fcf512193d2b701e92efcfa08de97064f779"
3351+
integrity sha512-+hWE8ZzafsElA6xTrVK/XbEpomhiPJDzKO085OJ5GJE6qzx/MGZ5J+EwD3KR+5/1+K+gtVwowF/Q39pgj+jNoQ==
33683352
dependencies:
3369-
"@keep-network/keep-core" "1.8.1-goerli.0"
3370-
"@keep-network/sortition-pools" "1.2.0-dev.1"
3371-
"@openzeppelin/upgrades" "^2.7.2"
3372-
openzeppelin-solidity "2.3.0"
3373-
3374-
"@keep-network/keep-ecdsa@development":
3375-
version "1.9.0-dev.1"
3376-
resolved "https://registry.yarnpkg.com/@keep-network/keep-ecdsa/-/keep-ecdsa-1.9.0-dev.1.tgz#7522b47dd639ddd7479a0e71dc328a9e0bba7cae"
3377-
integrity sha512-FRIDejTUiQO7c9gBXgjtTp2sXkEQKFBBqVjYoZE20OCGRxbgum9FbgD/B5RWIctBy4GGr5wJHnA1789iaK3X6A==
3378-
dependencies:
3379-
"@keep-network/keep-core" "1.8.0-dev.5"
3353+
"@keep-network/keep-core" "1.8.1-sepolia.0"
33803354
"@keep-network/sortition-pools" "1.2.0-dev.1"
33813355
"@openzeppelin/upgrades" "^2.7.2"
33823356
openzeppelin-solidity "2.3.0"
@@ -3399,15 +3373,15 @@
33993373
"@thesis/solidity-contracts" "github:thesis/solidity-contracts#4985bcf"
34003374
"@threshold-network/solidity-contracts" "1.2.1"
34013375

3402-
"@keep-network/random-beacon@development":
3403-
version "2.1.0-dev.10"
3404-
resolved "https://registry.yarnpkg.com/@keep-network/random-beacon/-/random-beacon-2.1.0-dev.10.tgz#61c9d3e98257f40292264f4b9e1991acdc11f3c3"
3405-
integrity sha512-NJtmjrzFimL20bul6g8lKxUPNc+lpiu9BJ3uheJOCWDL5vQ+hJGctmWqd63mvtjgO8Ks9IQsDg9wpValzSzGXg==
3376+
"@keep-network/random-beacon@^2.1.0-sepolia.1":
3377+
version "2.1.0-sepolia.1"
3378+
resolved "https://registry.yarnpkg.com/@keep-network/random-beacon/-/random-beacon-2.1.0-sepolia.1.tgz#3debde13d5f365883d88b3c1d279cc7d21984d58"
3379+
integrity sha512-dj6j6/msv1BqMtPbVoLo4cMhbtf4jLhKjkXmJoBXU2KYWW9wBlRB06M4DZPfUhhW8L7/1eaFJJIINATt26wBjA==
34063380
dependencies:
3407-
"@keep-network/sortition-pools" "^2.0.0-pre.16"
3408-
"@openzeppelin/contracts" "^4.6.0"
3381+
"@keep-network/sortition-pools" "github:keep-network/sortition-pools#test-fork"
3382+
"@openzeppelin/contracts" "4.7.3"
34093383
"@thesis/solidity-contracts" "github:thesis/solidity-contracts#4985bcf"
3410-
"@threshold-network/solidity-contracts" "1.3.0-dev.5"
3384+
"@threshold-network/solidity-contracts" "1.3.0-sepolia.0"
34113385

34123386
"@keep-network/[email protected]":
34133387
version "1.1.2"
@@ -3423,14 +3397,21 @@
34233397
dependencies:
34243398
"@openzeppelin/contracts" "^2.4.0"
34253399

3426-
"@keep-network/[email protected]", "@keep-network/sortition-pools@^2.0.0-pre.16":
3400+
"@keep-network/[email protected]":
34273401
version "2.0.0"
34283402
resolved "https://registry.yarnpkg.com/@keep-network/sortition-pools/-/sortition-pools-2.0.0.tgz#04e29ec756d74e00d13505a3e2a7763b06d7a08d"
34293403
integrity sha512-82pDOKcDBvHBFblCt0ALVr6qC6mxk339ZqnCfYx1zIPaPhzkw1RKOv28AqPoqzhzcdqLIoPh8g9RS/M2Lplh1A==
34303404
dependencies:
34313405
"@openzeppelin/contracts" "^4.3.2"
34323406
"@thesis/solidity-contracts" "github:thesis/solidity-contracts#4985bcf"
34333407

3408+
"@keep-network/sortition-pools@github:keep-network/sortition-pools#test-fork":
3409+
version "2.1.0-pre"
3410+
resolved "https://codeload.github.com/keep-network/sortition-pools/tar.gz/a41007f4c818864cdca0b6a6446424c071157ced"
3411+
dependencies:
3412+
"@openzeppelin/contracts" "^4.3.2"
3413+
"@thesis/solidity-contracts" "github:thesis/solidity-contracts#4985bcf"
3414+
34343415
"@keep-network/tbtc-v2.ts@^2.4.1":
34353416
version "2.4.1"
34363417
resolved "https://registry.yarnpkg.com/@keep-network/tbtc-v2.ts/-/tbtc-v2.ts-2.4.1.tgz#177046b32859fe5ad429f52c081e3cac994d3700"
@@ -3473,13 +3454,13 @@
34733454
"@summa-tx/relay-sol" "^2.0.2"
34743455
openzeppelin-solidity "2.3.0"
34753456

3476-
"@keep-network/tbtc@development":
3477-
version "1.1.2-dev.1"
3478-
resolved "https://registry.yarnpkg.com/@keep-network/tbtc/-/tbtc-1.1.2-dev.1.tgz#dd1e734c0fed50474c74d7170c8749127231d1f9"
3479-
integrity sha512-IRa0j1D7JBG8UpduaFxkaq2Ii6F61HhNMUBmxr7kAIZwj/yx8sYXWi921mn0L2Z+hAYNcwEUVhCM91VKQH29pQ==
3457+
"@keep-network/tbtc@^1.1.2-sepolia.0":
3458+
version "1.1.2-sepolia.0"
3459+
resolved "https://registry.yarnpkg.com/@keep-network/tbtc/-/tbtc-1.1.2-sepolia.0.tgz#6ef5f511a5ce80133f892f564c81b45afb9eaec9"
3460+
integrity sha512-p5H728tyG/Frli3N0//u4JiqFxiuW4uzMrMmnJFO7azBJPhdwEALhHRsIX6BNkVH2/NRnmu3MQYksqNnUYM6Bg==
34803461
dependencies:
34813462
"@celo/contractkit" "^1.0.2"
3482-
"@keep-network/keep-ecdsa" ">1.9.0-dev <1.9.0-ropsten"
3463+
"@keep-network/keep-ecdsa" "1.9.0-sepolia.0"
34833464
"@summa-tx/bitcoin-spv-sol" "^3.1.0"
34843465
"@summa-tx/relay-sol" "^2.0.2"
34853466
openzeppelin-solidity "2.3.0"
@@ -3746,6 +3727,11 @@
37463727
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.5.2.tgz#90d9e47bacfd8693bfad0ac8a394645575528d05"
37473728
integrity sha512-xgWZYaPlrEOQo3cBj97Ufiuv79SPd8Brh4GcFYhPgb6WvAq4ppz8dWKL6h+jLAK01rUqMRp/TS9AdXgAeNvCLA==
37483729

3730+
"@openzeppelin/[email protected]":
3731+
version "4.7.3"
3732+
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-4.7.3.tgz#939534757a81f8d69cc854c7692805684ff3111e"
3733+
integrity sha512-dGRS0agJzu8ybo44pCIf3xBaPQN/65AIXNgK8+4gzKd5kbvlqyxryUYVLJv7fK98Seyd2hDZzVEHSWAh0Bt1Yw==
3734+
37493735
"@openzeppelin/contracts@^2.4.0":
37503736
version "2.5.1"
37513737
resolved "https://registry.yarnpkg.com/@openzeppelin/contracts/-/contracts-2.5.1.tgz#c76e3fc57aa224da3718ec351812a4251289db31"
@@ -4406,12 +4392,12 @@
44064392
"@openzeppelin/contracts-upgradeable" "~4.5.2"
44074393
"@thesis/solidity-contracts" "github:thesis/solidity-contracts#4985bcf"
44084394

4409-
"@threshold-network/[email protected]dev.5", "@threshold-network/solidity-contracts@development":
4410-
version "1.3.0-dev.5"
4411-
resolved "https://registry.yarnpkg.com/@threshold-network/solidity-contracts/-/solidity-contracts-1.3.0-dev.5.tgz#f7a2727d627a10218f0667bc0d33e19ed8f87fdc"
4412-
integrity sha512-AInTKQkJ0PKa32q2m8GnZFPYEArsnvOwhIFdBFaHdq9r4EGyqHMf4YY1WjffkheBZ7AQ0DNA8Lst30kBoQd0SA==
4395+
"@threshold-network/[email protected]sepolia.0", "@threshold-network/solidity-contracts@^1.3.0-sepolia.0":
4396+
version "1.3.0-sepolia.0"
4397+
resolved "https://registry.yarnpkg.com/@threshold-network/solidity-contracts/-/solidity-contracts-1.3.0-sepolia.0.tgz#9a2401094ca267844e08d1a5be1214d32bd99f93"
4398+
integrity sha512-FmRsi+WZAG805kpPYRWAeMbEDRDH44Af+q8UuyVKpjJh5ObcNz9MPGESeYflE1o8MsNpY1mfxZBY6olXPR/LCw==
44134399
dependencies:
4414-
"@keep-network/keep-core" ">1.8.1-dev <1.8.1-goerli"
4400+
"@keep-network/keep-core" "1.8.1-sepolia.0"
44154401
"@openzeppelin/contracts" "~4.5.0"
44164402
"@openzeppelin/contracts-upgradeable" "~4.5.2"
44174403
"@thesis/solidity-contracts" "github:thesis/solidity-contracts#4985bcf"

0 commit comments

Comments
 (0)