Skip to content

Commit

Permalink
feat: add function to withdraw delegator rewards
Browse files Browse the repository at this point in the history
  • Loading branch information
fbac committed Nov 4, 2024
1 parent 043e776 commit 16c9f6d
Show file tree
Hide file tree
Showing 16 changed files with 968 additions and 29 deletions.
1 change: 1 addition & 0 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ func New(
&app.FungibleKeeper,
app.StakingKeeper,
app.BankKeeper,
app.DistrKeeper,
appCodec,
storetypes.TransientGasConfig(),
),
Expand Down
12 changes: 11 additions & 1 deletion precompiles/precompiles.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdktypes "github.com/cosmos/cosmos-sdk/types"
bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
distrkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
"github.com/ethereum/go-ethereum/common"
"github.com/ethereum/go-ethereum/core/vm"
Expand All @@ -31,6 +32,7 @@ func StatefulContracts(
fungibleKeeper *fungiblekeeper.Keeper,
stakingKeeper *stakingkeeper.Keeper,
bankKeeper bankkeeper.Keeper,
distributionKeeper distrkeeper.Keeper,
cdc codec.Codec,
gasConfig storetypes.GasConfig,
) (precompiledContracts []evmkeeper.CustomContractFn) {
Expand All @@ -50,7 +52,15 @@ func StatefulContracts(
// Define the staking contract function.
if EnabledStatefulContracts[staking.ContractAddress] {
stakingContract := func(ctx sdktypes.Context, _ ethparams.Rules) vm.PrecompiledContract {
return staking.NewIStakingContract(ctx, stakingKeeper, *fungibleKeeper, bankKeeper, cdc, gasConfig)
return staking.NewIStakingContract(
ctx,
stakingKeeper,
*fungibleKeeper,
bankKeeper,
distributionKeeper,
cdc,
gasConfig,
)
}

// Append the staking contract to the precompiledContracts slice.
Expand Down
9 changes: 8 additions & 1 deletion precompiles/precompiles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,14 @@ func Test_StatefulContracts(t *testing.T) {
}

// StatefulContracts() should return all the enabled contracts.
contracts := StatefulContracts(k, &sdkk.StakingKeeper, sdkk.BankKeeper, appCodec, gasConfig)
contracts := StatefulContracts(
k,
&sdkk.StakingKeeper,
sdkk.BankKeeper,
sdkk.DistributionKeeper,
appCodec,
gasConfig,
)
require.NotNil(t, contracts, "StatefulContracts() should not return a nil slice")
require.Len(t, contracts, expectedContracts, "StatefulContracts() should return all the enabled contracts")

Expand Down
104 changes: 104 additions & 0 deletions precompiles/staking/IStaking.abi
Original file line number Diff line number Diff line change
@@ -1,4 +1,29 @@
[
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "claim_address",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "zrc20_token",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ClaimedRewards",
"type": "event"
},
{
"anonymous": false,
"inputs": [
Expand Down Expand Up @@ -105,6 +130,30 @@
"name": "Unstake",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "delegator",
"type": "address"
},
{
"internalType": "string",
"name": "validator",
"type": "string"
}
],
"name": "claimRewards",
"outputs": [
{
"internalType": "bool",
"name": "success",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down Expand Up @@ -164,6 +213,61 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "delegator",
"type": "address"
}
],
"name": "getDelegatorValidators",
"outputs": [
{
"internalType": "string[]",
"name": "validators",
"type": "string[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "delegator",
"type": "address"
},
{
"internalType": "string",
"name": "validator",
"type": "string"
}
],
"name": "getRewards",
"outputs": [
{
"components": [
{
"internalType": "string",
"name": "denom",
"type": "string"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"internalType": "struct DecCoin[]",
"name": "rewards",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
Expand Down
245 changes: 244 additions & 1 deletion precompiles/staking/IStaking.gen.go

Large diffs are not rendered by default.

104 changes: 104 additions & 0 deletions precompiles/staking/IStaking.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,30 @@
{
"abi": [
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "claim_address",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "zrc20_token",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "ClaimedRewards",
"type": "event"
},
{
"anonymous": false,
"inputs": [
Expand Down Expand Up @@ -106,6 +131,30 @@
"name": "Unstake",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "delegator",
"type": "address"
},
{
"internalType": "string",
"name": "validator",
"type": "string"
}
],
"name": "claimRewards",
"outputs": [
{
"internalType": "bool",
"name": "success",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down Expand Up @@ -165,6 +214,61 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "delegator",
"type": "address"
}
],
"name": "getDelegatorValidators",
"outputs": [
{
"internalType": "string[]",
"name": "validators",
"type": "string[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "delegator",
"type": "address"
},
{
"internalType": "string",
"name": "validator",
"type": "string"
}
],
"name": "getRewards",
"outputs": [
{
"components": [
{
"internalType": "string",
"name": "denom",
"type": "string"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"internalType": "struct DecCoin[]",
"name": "rewards",
"type": "tuple[]"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
Expand Down
41 changes: 41 additions & 0 deletions precompiles/staking/IStaking.sol
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,13 @@ struct Validator {
BondStatus bondStatus;
}

/// @notice Cosmos coin representation.abi
/// ref: https://github.com/cosmos/cosmos-sdk/blob/470e0859462b28a53adb411843539561d11d7bf5/x/distribution/README.md?plain=1#L139
struct DecCoin {
string denom;
uint256 amount;
}

interface IStaking {
/// @notice Stake event is emitted when stake function is called
/// @param staker Staker address
Expand Down Expand Up @@ -66,6 +73,16 @@ interface IStaking {
uint256 amount
);

/// @notice ClaimedRewards is emitted when a delegator claims ZRC20.
/// @param claim_address Distributor address.
/// @param zrc20_token ZRC20 token address.
/// @param amount Claimed amount.
event ClaimedRewards(
address indexed claim_address,
address indexed zrc20_token,
uint256 amount
);

/// @notice Stake coins to validator
/// @param staker Staker address
/// @param validator Validator address
Expand Down Expand Up @@ -123,4 +140,28 @@ interface IStaking {
address zrc20,
uint256 amount
) external returns (bool success);

/// @notice Claim ZRC20 staking rewards.
/// @param validator The validator address to claim rewards from.
/// @return success Boolean indicating whether the claim was successful.
function claimRewards(
address delegator,
string memory validator
) external returns (bool success);

/// @dev Queries all validators the delegator has delegated to.
/// @param delegator The delegator address to query rewards from.
/// @return validators List of the validators the caller has delegated to.
function getDelegatorValidators(
address delegator
) external view returns (string[] calldata validators);

/// @notice Query ZRC20 outstanding staking rewards.
/// @param delegator The delegator address to query rewards from.
/// @param validator The validator address to query rewards from.
/// @return rewards The list of coins rewarded on the validator.
function getRewards(
address delegator,
string memory validator
) external view returns (DecCoin[] calldata rewards);
}
Loading

0 comments on commit 16c9f6d

Please sign in to comment.