Skip to content

Add multicall to staking contract + keep legacy bulk calls #550

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file not shown.
3 changes: 2 additions & 1 deletion cli/commands/contracts/staking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ export const allocate = async (cli: CLIEnvironment, cliArgs: CLIArgs): Promise<v
const staking = cli.contracts.Staking

logger.info(`Allocating ${cliArgs.amount} tokens on ${subgraphDeploymentID}...`)
await sendTransaction(cli.wallet, staking, 'allocate', [
await sendTransaction(cli.wallet, staking, 'allocateFrom', [
cli.walletAddress,
subgraphDeploymentID,
amount,
allocationID,
Expand Down
3 changes: 2 additions & 1 deletion contracts/staking/Staking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ pragma experimental ABIEncoderV2;

import "@openzeppelin/contracts/cryptography/ECDSA.sol";

import "../base/Multicall.sol";
import "../upgrades/GraphUpgradeable.sol";
import "../utils/TokenUtils.sol";

Expand All @@ -20,7 +21,7 @@ import "./libs/Stakes.sol";
* Allocations on a Subgraph. It also allows Delegators to Delegate towards an Indexer. The
* contract also has the slashing functionality.
*/
contract Staking is StakingV2Storage, GraphUpgradeable, IStaking {
contract Staking is StakingV2Storage, GraphUpgradeable, IStaking, Multicall {
using SafeMath for uint256;
using Stakes for Stakes.Indexer;
using Rebates for Rebates.Pool;
Expand Down
6 changes: 4 additions & 2 deletions test/disputes/poi.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ describe('DisputeManager:POI', async () => {
await staking.connect(indexerAccount.signer).stake(indexerTokens)
await staking
.connect(indexerAccount.signer)
.allocate(
.allocateFrom(
indexerAccount.address,
subgraphDeploymentID,
indexerAllocatedTokens,
allocationID,
Expand Down Expand Up @@ -147,7 +148,8 @@ describe('DisputeManager:POI', async () => {
await staking.connect(indexer.signer).stake(indexerTokens)
const tx1 = await staking
.connect(indexer.signer)
.allocate(
.allocateFrom(
indexer.address,
subgraphDeploymentID,
indexerAllocatedTokens,
allocationID,
Expand Down
6 changes: 4 additions & 2 deletions test/disputes/query.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,8 @@ describe('DisputeManager:Query', async () => {
await staking.connect(indexerAccount.signer).stake(indexerTokens)
await staking
.connect(indexerAccount.signer)
.allocate(
.allocateFrom(
indexerAccount.address,
dispute.receipt.subgraphDeploymentID,
indexerAllocatedTokens,
allocationID,
Expand Down Expand Up @@ -194,7 +195,8 @@ describe('DisputeManager:Query', async () => {
await staking.connect(indexer.signer).stake(indexerTokens)
const tx1 = await staking
.connect(indexer.signer)
.allocate(
.allocateFrom(
indexer.address,
dispute.receipt.subgraphDeploymentID,
indexerAllocatedTokens,
indexer1ChannelKey.address,
Expand Down
3 changes: 2 additions & 1 deletion test/payments/allocationExchange.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ describe('AllocationExchange', () => {
await staking.connect(indexer.signer).stake(stakeTokens)
await staking
.connect(indexer.signer)
.allocate(
.allocateFrom(
indexer.address,
subgraphDeploymentID,
stakeTokens,
allocationID,
Expand Down
3 changes: 2 additions & 1 deletion test/payments/withdrawHelper.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,8 @@ describe('WithdrawHelper', () => {
await staking.connect(indexer.signer).stake(stakeTokens)
await staking
.connect(indexer.signer)
.allocate(
.allocateFrom(
indexer.address,
subgraphDeploymentID,
stakeTokens,
allocationID,
Expand Down
18 changes: 12 additions & 6 deletions test/rewards/rewards.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,8 @@ describe('Rewards', () => {
await staking.connect(indexer1.signer).stake(tokensToAllocate)
await staking
.connect(indexer1.signer)
.allocate(
.allocateFrom(
indexer1.address,
subgraphDeploymentID1,
tokensToAllocate,
allocationID,
Expand Down Expand Up @@ -428,7 +429,8 @@ describe('Rewards', () => {
await staking.connect(indexer1.signer).stake(tokensToAllocate)
await staking
.connect(indexer1.signer)
.allocate(
.allocateFrom(
indexer1.address,
subgraphDeploymentID1,
tokensToAllocate,
allocationID,
Expand Down Expand Up @@ -471,7 +473,8 @@ describe('Rewards', () => {
await staking.connect(indexer1.signer).stake(tokensToAllocate)
await staking
.connect(indexer1.signer)
.allocate(
.allocateFrom(
indexer1.address,
subgraphDeploymentID1,
tokensToAllocate,
allocationID,
Expand Down Expand Up @@ -516,7 +519,8 @@ describe('Rewards', () => {
await staking.connect(indexer1.signer).stake(tokensToAllocate)
await staking
.connect(indexer1.signer)
.allocate(
.allocateFrom(
indexer1.address,
subgraphDeploymentID1,
tokensToAllocate,
allocationID,
Expand Down Expand Up @@ -558,7 +562,8 @@ describe('Rewards', () => {
// Allocate
await staking
.connect(indexer1.signer)
.allocate(
.allocateFrom(
indexer1.address,
subgraphDeploymentID1,
tokensToAllocate,
allocationID,
Expand Down Expand Up @@ -754,7 +759,8 @@ describe('Rewards', () => {
await staking.connect(indexer1.signer).stake(tokensToAllocate)
await staking
.connect(indexer1.signer)
.allocate(
.allocateFrom(
indexer1.address,
subgraphDeploymentID1,
tokensToAllocate,
allocationID,
Expand Down
83 changes: 52 additions & 31 deletions test/staking/allocation.test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from 'chai'
import { constants, BigNumber } from 'ethers'
import { constants, BigNumber, PopulatedTransaction } from 'ethers'

import { Curation } from '../../build/types/Curation'
import { EpochManager } from '../../build/types/EpochManager'
Expand Down Expand Up @@ -67,7 +67,8 @@ describe('Staking:Allocation', () => {
const allocate = async (tokens: BigNumber) => {
return staking
.connect(indexer.signer)
.allocate(
.allocateFrom(
indexer.address,
subgraphDeploymentID,
tokens,
allocationID,
Expand Down Expand Up @@ -206,7 +207,14 @@ describe('Staking:Allocation', () => {
it('reject allocate with invalid allocationID', async function () {
const tx = staking
.connect(indexer.signer)
.allocate(subgraphDeploymentID, tokensToAllocate, AddressZero, metadata, randomHexBytes(20))
.allocateFrom(
indexer.address,
subgraphDeploymentID,
tokensToAllocate,
AddressZero,
metadata,
randomHexBytes(20),
)
await expect(tx).revertedWith('!alloc')
})

Expand Down Expand Up @@ -273,7 +281,8 @@ describe('Staking:Allocation', () => {
const invalidProof = await channelKey.generateProof(randomHexBytes(20))
const tx = staking
.connect(indexer.signer)
.allocate(
.allocateFrom(
indexer.address,
subgraphDeploymentID,
tokensToAllocate,
indexer.address,
Expand All @@ -286,7 +295,8 @@ describe('Staking:Allocation', () => {
it('invalid proof signature format', async function () {
const tx = staking
.connect(indexer.signer)
.allocate(
.allocateFrom(
indexer.address,
subgraphDeploymentID,
tokensToAllocate,
indexer.address,
Expand Down Expand Up @@ -631,7 +641,8 @@ describe('Staking:Allocation', () => {
const allocationID2 = channelKey2.address
await staking
.connect(indexer.signer)
.allocate(
.allocateFrom(
indexer.address,
subgraphDeploymentID,
tokensToAllocate,
allocationID2,
Expand All @@ -644,17 +655,21 @@ describe('Staking:Allocation', () => {
await advanceToNextEpoch(epochManager)

// Close multiple allocations in one tx
const requests = [
{
allocationID: allocationID,
poi: poi,
},
{
allocationID: allocationID2,
poi: poi,
},
]
await staking.connect(indexer.signer).closeAllocationMany(requests)
const requests = await Promise.all(
[
{
allocationID: allocationID,
poi: poi,
},
{
allocationID: allocationID2,
poi: poi,
},
].map(({ allocationID, poi }) =>
staking.connect(indexer.signer).populateTransaction.closeAllocation(allocationID, poi),
),
).then((e) => e.map((e: PopulatedTransaction) => e.data))
await staking.connect(indexer.signer).multicall(requests)
})
})

Expand All @@ -672,19 +687,22 @@ describe('Staking:Allocation', () => {
// Close and allocate
const newChannelKey = deriveChannelKey()
const newAllocationID = newChannelKey.address
const tx = staking
.connect(indexer.signer)
.closeAndAllocate(
allocationID,
HashZero,
indexer.address,
subgraphDeploymentID,
tokensToAllocate,
newAllocationID,
metadata,
await newChannelKey.generateProof(indexer.address),
)
await tx

// Close multiple allocations in one tx
const requests = await Promise.all([
staking.connect(indexer.signer).populateTransaction.closeAllocation(allocationID, poi),
staking
.connect(indexer.signer)
.populateTransaction.allocateFrom(
indexer.address,
subgraphDeploymentID,
tokensToAllocate,
newAllocationID,
metadata,
await newChannelKey.generateProof(indexer.address),
),
]).then((e) => e.map((e: PopulatedTransaction) => e.data))
await staking.connect(indexer.signer).multicall(requests)
})
})

Expand Down Expand Up @@ -870,7 +888,10 @@ describe('Staking:Allocation', () => {

// Claim with restake
expect(await staking.getAllocationState(allocationID)).eq(AllocationState.Finalized)
await staking.connect(indexer.signer).claimMany([allocationID], true)
const tx = await staking
.connect(indexer.signer)
.populateTransaction.claim(allocationID, true)
await staking.connect(indexer.signer).multicall([tx.data])

// Verify that the claimed tokens are restaked
const afterIndexerStake = await staking.getIndexerStakedTokens(indexer.address)
Expand Down
3 changes: 2 additions & 1 deletion test/staking/delegation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -534,7 +534,8 @@ describe('Staking::Delegation', () => {
const setupAllocation = async (tokens: BigNumber) => {
return staking
.connect(indexer.signer)
.allocate(
.allocateFrom(
indexer.address,
subgraphDeploymentID,
tokens,
allocationID,
Expand Down
3 changes: 2 additions & 1 deletion test/staking/staking.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ describe('Staking:Stakes', () => {
const allocate = async (tokens: BigNumber) => {
return staking
.connect(indexer.signer)
.allocate(
.allocateFrom(
indexer.address,
subgraphDeploymentID,
tokens,
allocationID,
Expand Down