cfx_executor/internal_contract/contracts/
staking.rs

1// Copyright 2020 Conflux Foundation. All rights reserved.
2// Conflux is free software and distributed under GNU General Public License.
3// See http://www.gnu.org/licenses/
4
5use cfx_parameters::internal_contract_addresses::STORAGE_INTEREST_STAKING_CONTRACT_ADDRESS;
6use cfx_types::{Address, U256};
7
8use super::{super::impls::staking::*, preludes::*};
9
10// Definitions for the whole contract.
11make_solidity_contract! {
12    pub struct Staking(STORAGE_INTEREST_STAKING_CONTRACT_ADDRESS, generate_fn_table, "active_at_genesis");
13}
14fn generate_fn_table() -> SolFnTable {
15    make_function_table!(
16        Deposit,
17        Withdraw,
18        VoteLock,
19        GetStakingBalance,
20        GetLockedStakingBalance,
21        GetVotePower
22    )
23}
24group_impl_is_active!(
25    "genesis",
26    Deposit,
27    Withdraw,
28    VoteLock,
29    GetStakingBalance,
30    GetLockedStakingBalance,
31    GetVotePower
32);
33
34make_solidity_function! {
35    struct Deposit(U256,"deposit(uint256)");
36}
37impl_function_type!(Deposit, "non_payable_write");
38
39impl UpfrontPaymentTrait for Deposit {
40    fn upfront_gas_payment(
41        &self, _: &Self::Input, params: &ActionParams,
42        context: &InternalRefContext,
43    ) -> DbResult<U256> {
44        let length = context.state.deposit_list_length(&params.sender)?;
45        Ok(U256::from(2 * context.spec.sstore_reset_gas)
46            * U256::from(length + 1))
47    }
48}
49
50impl SimpleExecutionTrait for Deposit {
51    fn execute_inner(
52        &self, input: U256, params: &ActionParams,
53        context: &mut InternalRefContext,
54    ) -> vm::Result<()> {
55        deposit(
56            input,
57            params,
58            context.env,
59            context.spec,
60            context.state,
61            context.tracer,
62        )
63    }
64}
65
66make_solidity_function! {
67    struct Withdraw(U256,"withdraw(uint256)");
68}
69impl_function_type!(Withdraw, "non_payable_write");
70
71impl UpfrontPaymentTrait for Withdraw {
72    fn upfront_gas_payment(
73        &self, _input: &Self::Input, params: &ActionParams,
74        context: &InternalRefContext,
75    ) -> DbResult<U256> {
76        if context.spec.cip97 {
77            return Ok(U256::from(2 * context.spec.cold_sload_gas));
78        }
79        let length = context.state.deposit_list_length(&params.sender)?;
80        Ok(U256::from(2 * context.spec.sstore_reset_gas) * U256::from(length))
81    }
82}
83
84impl SimpleExecutionTrait for Withdraw {
85    fn execute_inner(
86        &self, input: U256, params: &ActionParams,
87        context: &mut InternalRefContext,
88    ) -> vm::Result<()> {
89        withdraw(
90            input,
91            params,
92            context.env,
93            context.spec,
94            context.state,
95            context.tracer,
96        )
97    }
98}
99
100make_solidity_function! {
101    struct VoteLock((U256, U256), "voteLock(uint256,uint256)");
102}
103impl_function_type!(VoteLock, "non_payable_write");
104
105impl UpfrontPaymentTrait for VoteLock {
106    fn upfront_gas_payment(
107        &self, _input: &Self::Input, params: &ActionParams,
108        context: &InternalRefContext,
109    ) -> DbResult<U256> {
110        let length = context.state.vote_stake_list_length(&params.sender)?;
111        Ok(U256::from(2 * context.spec.sstore_reset_gas) * U256::from(length))
112    }
113}
114
115impl SimpleExecutionTrait for VoteLock {
116    fn execute_inner(
117        &self, inputs: (U256, U256), params: &ActionParams,
118        context: &mut InternalRefContext,
119    ) -> vm::Result<()> {
120        vote_lock(inputs.0, inputs.1, params, context.env, context.state)
121    }
122}
123
124make_solidity_function! {
125    struct GetStakingBalance(Address, "getStakingBalance(address)", U256);
126}
127impl_function_type!(GetStakingBalance, "query_with_default_gas");
128
129impl SimpleExecutionTrait for GetStakingBalance {
130    fn execute_inner(
131        &self, input: Address, _: &ActionParams,
132        context: &mut InternalRefContext,
133    ) -> vm::Result<U256> {
134        Ok(context.state.staking_balance(&input)?)
135    }
136}
137
138make_solidity_function! {
139    struct GetLockedStakingBalance((Address,U256), "getLockedStakingBalance(address,uint256)", U256);
140}
141impl_function_type!(GetLockedStakingBalance, "query");
142
143impl UpfrontPaymentTrait for GetLockedStakingBalance {
144    fn upfront_gas_payment(
145        &self, (address, _): &(Address, U256), _: &ActionParams,
146        context: &InternalRefContext,
147    ) -> DbResult<U256> {
148        let length = context.state.vote_stake_list_length(address)?;
149        Ok(U256::from(context.spec.cold_sload_gas) * U256::from(length + 1))
150    }
151}
152
153impl SimpleExecutionTrait for GetLockedStakingBalance {
154    fn execute_inner(
155        &self, (address, block_number): (Address, U256), _: &ActionParams,
156        context: &mut InternalRefContext,
157    ) -> vm::Result<U256> {
158        Ok(get_locked_staking(
159            address,
160            block_number,
161            context.env.number,
162            context.state,
163        )?)
164    }
165}
166
167make_solidity_function! {
168    struct GetVotePower((Address,U256), "getVotePower(address,uint256)", U256);
169}
170impl_function_type!(GetVotePower, "query");
171
172impl UpfrontPaymentTrait for GetVotePower {
173    fn upfront_gas_payment(
174        &self, (address, _): &(Address, U256), _: &ActionParams,
175        context: &InternalRefContext,
176    ) -> DbResult<U256> {
177        let length = context.state.vote_stake_list_length(address)?;
178        Ok(U256::from(context.spec.cold_sload_gas) * U256::from(length + 1))
179    }
180}
181
182impl SimpleExecutionTrait for GetVotePower {
183    fn execute_inner(
184        &self, (address, block_number): (Address, U256), _: &ActionParams,
185        context: &mut InternalRefContext,
186    ) -> vm::Result<U256> {
187        Ok(get_vote_power(
188            address,
189            block_number,
190            context.env.number,
191            context.state,
192        )?)
193    }
194}
195
196#[test]
197fn test_staking_contract_sig_v2() {
198    // Check the consistency between signature generated by rust code and java
199    // sdk.
200    check_func_signature!(GetStakingBalance, "b04ef9c2");
201    check_func_signature!(GetLockedStakingBalance, "b3657ee7");
202    check_func_signature!(GetVotePower, "c90abac8");
203    check_func_signature!(Deposit, "b6b55f25");
204    check_func_signature!(Withdraw, "2e1a7d4d");
205    check_func_signature!(VoteLock, "44a51d6d");
206}