mirror of https://github.com/nucypher/nucypher.git
StakingInterface: worklock commands
parent
536d55cfed
commit
ce684cce54
|
@ -48,8 +48,8 @@ from nucypher.blockchain.eth.decorators import validate_secret, validate_checksu
|
|||
from nucypher.blockchain.eth.interfaces import (
|
||||
BlockchainDeployerInterface,
|
||||
BlockchainInterfaceFactory,
|
||||
VersionedContract
|
||||
)
|
||||
VersionedContract,
|
||||
BlockchainInterface)
|
||||
from nucypher.blockchain.eth.registry import AllocationRegistry
|
||||
from nucypher.blockchain.eth.registry import BaseContractRegistry
|
||||
|
||||
|
@ -870,11 +870,20 @@ class StakingInterfaceDeployer(BaseContractDeployer, UpgradeableContractMixin):
|
|||
contract_name=policy_contract_name,
|
||||
proxy_name=policy_proxy_name)
|
||||
|
||||
worklock_name = WorklockDeployer.contract_name
|
||||
try:
|
||||
self.worklock_contract = self.blockchain.get_contract_by_name(registry=self.registry,
|
||||
contract_name=worklock_name)
|
||||
except BaseContractRegistry.UnknownContract:
|
||||
self.worklock_contract = None
|
||||
|
||||
def _deploy_essential(self, contract_version: str, gas_limit: int = None, confirmations: int = 0):
|
||||
"""Note: These parameters are order-sensitive"""
|
||||
worklock_address = self.worklock_contract.address if self.worklock_contract else BlockchainInterface.NULL_ADDRESS
|
||||
constructor_args = (self.token_contract.address,
|
||||
self.staking_contract.address,
|
||||
self.policy_contract.address)
|
||||
self.policy_contract.address,
|
||||
worklock_address)
|
||||
|
||||
contract, deployment_receipt = self.blockchain.deploy_contract(self.deployer_address,
|
||||
self.registry,
|
||||
|
|
|
@ -194,7 +194,7 @@ contract PolicyManager is Upgradeable {
|
|||
/**
|
||||
* @notice Get the minimum reward rate acceptable by node
|
||||
*/
|
||||
function getMinRewardRate(NodeInfo storage _nodeInfo) internal returns (uint256) {
|
||||
function getMinRewardRate(NodeInfo storage _nodeInfo) internal view returns (uint256) {
|
||||
// if minRewardRate has not been set or is outside the acceptable range
|
||||
if (_nodeInfo.minRewardRate == 0 ||
|
||||
_nodeInfo.minRewardRate < minRewardRateRange.min ||
|
||||
|
@ -208,7 +208,7 @@ contract PolicyManager is Upgradeable {
|
|||
/**
|
||||
* @notice Get the minimum reward rate acceptable by node
|
||||
*/
|
||||
function getMinRewardRate(address _node) public returns (uint256) {
|
||||
function getMinRewardRate(address _node) public view returns (uint256) {
|
||||
NodeInfo storage nodeInfo = nodes[_node];
|
||||
return getMinRewardRate(nodeInfo);
|
||||
}
|
||||
|
|
|
@ -62,7 +62,7 @@ contract AbstractStakingContract {
|
|||
* @dev Checks permission for calling fallback function
|
||||
*/
|
||||
function isFallbackAllowed() public returns (bool);
|
||||
|
||||
|
||||
/**
|
||||
* @dev Withdraw tokens from staking contract
|
||||
*/
|
||||
|
|
|
@ -5,13 +5,14 @@ import "contracts/staking_contracts/AbstractStakingContract.sol";
|
|||
import "contracts/NuCypherToken.sol";
|
||||
import "contracts/StakingEscrow.sol";
|
||||
import "contracts/PolicyManager.sol";
|
||||
import "contracts/WorkLock.sol";
|
||||
|
||||
|
||||
/**
|
||||
* @notice Interface for accessing main contracts from a staking contract
|
||||
* @dev All methods must be stateless because this code will be executed by delegatecall call.
|
||||
* If state is needed - use getStateContract() method to access state of this contract.
|
||||
* @dev |v1.3.1|
|
||||
* @dev |v1.4.1|
|
||||
*/
|
||||
contract StakingInterface {
|
||||
|
||||
|
@ -27,30 +28,41 @@ contract StakingInterface {
|
|||
event WorkerSet(address indexed sender, address worker);
|
||||
event Prolonged(address indexed sender, uint256 index, uint16 periods);
|
||||
event WindDownSet(address indexed sender, bool windDown);
|
||||
event Bid(address indexed sender, uint256 depositedETH);
|
||||
event Claimed(address indexed sender, uint256 claimedTokens);
|
||||
event Refund(address indexed sender, uint256 refundETH);
|
||||
event BidCanceled(address indexed sender);
|
||||
event CompensationWithdrawn(address indexed sender);
|
||||
|
||||
NuCypherToken public token;
|
||||
StakingEscrow public escrow;
|
||||
PolicyManager public policyManager;
|
||||
WorkLock public workLock;
|
||||
|
||||
/**
|
||||
* @notice Constructor sets addresses of the contracts
|
||||
* @param _token Token contract
|
||||
* @param _escrow Escrow contract
|
||||
* @param _policyManager PolicyManager contract
|
||||
* @param _workLock WorkLock contract
|
||||
*/
|
||||
constructor(
|
||||
NuCypherToken _token,
|
||||
StakingEscrow _escrow,
|
||||
PolicyManager _policyManager
|
||||
PolicyManager _policyManager,
|
||||
WorkLock _workLock
|
||||
)
|
||||
public
|
||||
{
|
||||
require(_token.totalSupply() > 0 &&
|
||||
_escrow.secondsPerPeriod() > 0 &&
|
||||
_policyManager.secondsPerPeriod() > 0);
|
||||
_policyManager.secondsPerPeriod() > 0 &&
|
||||
// in case there is no worklock contract
|
||||
(address(_workLock) == address(0) || _workLock.startBidDate() > 0));
|
||||
token = _token;
|
||||
escrow = _escrow;
|
||||
policyManager = _policyManager;
|
||||
workLock = _workLock;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -185,4 +197,54 @@ contract StakingInterface {
|
|||
emit WindDownSet(msg.sender, _windDown);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Bid for tokens by transferring ETH
|
||||
*/
|
||||
function bid(uint256 _value) public payable {
|
||||
WorkLock workLockFromState = getStateContract().workLock();
|
||||
require(address(workLockFromState) != address(0));
|
||||
workLockFromState.bid.value(_value)();
|
||||
emit Bid(msg.sender, _value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Cancel bid and refund deposited ETH
|
||||
*/
|
||||
function cancelBid() public {
|
||||
WorkLock workLockFromState = getStateContract().workLock();
|
||||
require(address(workLockFromState) != address(0));
|
||||
workLockFromState.cancelBid();
|
||||
emit BidCanceled(msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Withdraw compensation after force refund
|
||||
*/
|
||||
function withdrawCompensation() public {
|
||||
WorkLock workLockFromState = getStateContract().workLock();
|
||||
require(address(workLockFromState) != address(0));
|
||||
workLockFromState.withdrawCompensation();
|
||||
emit CompensationWithdrawn(msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Claimed tokens will be deposited and locked as stake in the StakingEscrow contract.
|
||||
*/
|
||||
function claim() public {
|
||||
WorkLock workLockFromState = getStateContract().workLock();
|
||||
require(address(workLockFromState) != address(0));
|
||||
uint256 claimedTokens = workLockFromState.claim();
|
||||
emit Claimed(msg.sender, claimedTokens);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Refund ETH for the completed work
|
||||
*/
|
||||
function refund() public {
|
||||
WorkLock workLockFromState = getStateContract().workLock();
|
||||
require(address(workLockFromState) != address(0));
|
||||
uint256 refundETH = workLockFromState.refund();
|
||||
emit Refund(msg.sender, refundETH);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -113,6 +113,56 @@ contract PolicyManagerForStakingContractMock {
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notice Contract for staking contract tests
|
||||
*/
|
||||
contract WorkLockForStakingContractMock {
|
||||
|
||||
uint256 public startBidDate = 1;
|
||||
uint256 public claimed;
|
||||
uint256 public depositedETH;
|
||||
uint256 public compensation;
|
||||
uint256 public refundETH;
|
||||
|
||||
function bid() external payable {
|
||||
depositedETH = msg.value;
|
||||
}
|
||||
|
||||
function cancelBid() external {
|
||||
uint256 value = depositedETH;
|
||||
depositedETH = 0;
|
||||
msg.sender.transfer(value);
|
||||
}
|
||||
|
||||
function sendCompensation() external payable {
|
||||
compensation = msg.value;
|
||||
}
|
||||
|
||||
function withdrawCompensation() external {
|
||||
uint256 value = compensation;
|
||||
compensation = 0;
|
||||
msg.sender.transfer(value);
|
||||
}
|
||||
|
||||
function claim() external returns (uint256) {
|
||||
claimed += 1;
|
||||
return claimed;
|
||||
}
|
||||
|
||||
function sendRefund() external payable {
|
||||
refundETH = msg.value;
|
||||
}
|
||||
|
||||
function refund() external returns (uint256) {
|
||||
uint256 value = refundETH;
|
||||
refundETH = 0;
|
||||
msg.sender.transfer(value);
|
||||
return value;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notice Contract for staking contract tests
|
||||
*/
|
||||
|
|
|
@ -156,13 +156,13 @@ def generate_args_for_slashing(mock_ursula_reencrypts, ursula):
|
|||
|
||||
|
||||
@pytest.fixture()
|
||||
def staking_interface(testerchain, token, escrow, policy_manager, deploy_contract):
|
||||
def staking_interface(testerchain, token, escrow, policy_manager, worklock, deploy_contract):
|
||||
escrow, _ = escrow
|
||||
policy_manager, _ = policy_manager
|
||||
secret_hash = testerchain.w3.keccak(router_secret)
|
||||
# Creator deploys the staking interface
|
||||
staking_interface, _ = deploy_contract(
|
||||
'StakingInterface', token.address, escrow.address, policy_manager.address)
|
||||
'StakingInterface', token.address, escrow.address, policy_manager.address, worklock.address)
|
||||
router, _ = deploy_contract(
|
||||
'StakingInterfaceRouter', staking_interface.address, secret_hash)
|
||||
return staking_interface, router
|
||||
|
@ -331,6 +331,16 @@ def test_all(testerchain,
|
|||
tx = token.functions.approve(escrow.address, 0).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Create the first preallocation escrow
|
||||
preallocation_escrow_1, _ = deploy_contract(
|
||||
'PreallocationEscrow', staking_interface_router.address, token.address, escrow.address)
|
||||
preallocation_escrow_interface_1 = testerchain.client.get_contract(
|
||||
abi=staking_interface.abi,
|
||||
address=preallocation_escrow_1.address,
|
||||
ContractFactoryClass=Contract)
|
||||
tx = preallocation_escrow_1.functions.transferOwnership(staker3).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Initialize worklock
|
||||
worklock_supply = 3 * token_economics.minimum_allowed_locked + token_economics.maximum_allowed_locked
|
||||
tx = token.functions.approve(worklock.address, worklock_supply).transact({'from': creator})
|
||||
|
@ -366,10 +376,15 @@ def test_all(testerchain,
|
|||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Other stakers do bid
|
||||
assert worklock.functions.workInfo(staker4).call()[0] == 0
|
||||
tx = worklock.functions.bid().transact({'from': staker4, 'value': deposited_eth_2, 'gas_price': 0})
|
||||
assert worklock.functions.workInfo(preallocation_escrow_1.address).call()[0] == 0
|
||||
tx = testerchain.client.send_transaction(
|
||||
{'from': testerchain.client.coinbase, 'to': preallocation_escrow_1.address, 'value': deposited_eth_2})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.workInfo(staker4).call()[0] == deposited_eth_2
|
||||
assert testerchain.w3.eth.getBalance(preallocation_escrow_1.address) == deposited_eth_2
|
||||
tx = preallocation_escrow_interface_1.functions.bid(deposited_eth_2).transact({'from': staker3, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert testerchain.w3.eth.getBalance(preallocation_escrow_1.address) == 0
|
||||
assert worklock.functions.workInfo(preallocation_escrow_1.address).call()[0] == deposited_eth_2
|
||||
worklock_balance += deposited_eth_2
|
||||
bonus_worklock_supply -= min_stake
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == worklock_balance
|
||||
|
@ -396,11 +411,12 @@ def test_all(testerchain,
|
|||
|
||||
# One of stakers cancels bid
|
||||
assert worklock.functions.getBiddersLength().call() == 3
|
||||
tx = worklock.functions.cancelBid().transact({'from': staker4, 'gas_price': 0})
|
||||
tx = preallocation_escrow_interface_1.functions.cancelBid().transact({'from': staker3, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.workInfo(staker4).call()[0] == 0
|
||||
assert worklock.functions.workInfo(preallocation_escrow_1.address).call()[0] == 0
|
||||
worklock_balance -= deposited_eth_2
|
||||
bonus_worklock_supply += min_stake
|
||||
assert testerchain.w3.eth.getBalance(preallocation_escrow_1.address) == deposited_eth_2
|
||||
assert testerchain.w3.eth.getBalance(worklock.address) == worklock_balance
|
||||
assert worklock.functions.ethToTokens(deposited_eth_2).call() == min_stake
|
||||
assert worklock.functions.ethToTokens(2 * deposited_eth_2).call() == min_stake + bonus_worklock_supply // 18
|
||||
|
@ -499,17 +515,7 @@ def test_all(testerchain,
|
|||
tx = worklock.functions.refund().transact({'from': staker2, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Create the first preallocation escrow
|
||||
preallocation_escrow_1, _ = deploy_contract(
|
||||
'PreallocationEscrow', staking_interface_router.address, token.address, escrow.address)
|
||||
preallocation_escrow_interface_1 = testerchain.client.get_contract(
|
||||
abi=staking_interface.abi,
|
||||
address=preallocation_escrow_1.address,
|
||||
ContractFactoryClass=Contract)
|
||||
|
||||
# Set and lock re-stake parameter in first preallocation escrow
|
||||
tx = preallocation_escrow_1.functions.transferOwnership(staker3).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert not escrow.functions.stakerInfo(preallocation_escrow_1.address).call()[DISABLE_RE_STAKE_FIELD]
|
||||
current_period = escrow.functions.getCurrentPeriod().call()
|
||||
tx = preallocation_escrow_interface_1.functions.lockReStake(current_period + 22).transact({'from': staker3})
|
||||
|
@ -948,7 +954,7 @@ def test_all(testerchain,
|
|||
# Upgrade the preallocation escrow library
|
||||
# Deploy the same contract as the second version
|
||||
staking_interface_v2, _ = deploy_contract(
|
||||
'StakingInterface', token.address, escrow.address, policy_manager.address)
|
||||
'StakingInterface', token.address, escrow.address, policy_manager.address, worklock.address)
|
||||
router_secret2 = os.urandom(SECRET_LENGTH)
|
||||
router_secret2_hash = testerchain.w3.keccak(router_secret2)
|
||||
# Staker and Alice can't upgrade library, only owner can
|
||||
|
|
|
@ -50,10 +50,16 @@ def policy_manager(testerchain, deploy_contract):
|
|||
|
||||
|
||||
@pytest.fixture()
|
||||
def staking_interface(testerchain, token, escrow, policy_manager, deploy_contract):
|
||||
def worklock(testerchain, deploy_contract):
|
||||
contract, _ = deploy_contract('WorkLockForStakingContractMock')
|
||||
return contract
|
||||
|
||||
|
||||
@pytest.fixture()
|
||||
def staking_interface(testerchain, token, escrow, policy_manager, worklock, deploy_contract):
|
||||
# Creator deploys the staking interface
|
||||
contract, _ = deploy_contract(
|
||||
'StakingInterface', token.address, escrow.address, policy_manager.address)
|
||||
'StakingInterface', token.address, escrow.address, policy_manager.address, worklock.address)
|
||||
return contract
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,9 @@ import os
|
|||
import pytest
|
||||
from eth_utils import keccak
|
||||
from eth_tester.exceptions import TransactionFailed
|
||||
from web3.contract import Contract
|
||||
|
||||
from nucypher.blockchain.eth.interfaces import BlockchainInterface
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
|
@ -407,17 +410,13 @@ def test_policy(testerchain, policy_manager, preallocation_escrow, preallocation
|
|||
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_reentrancy(testerchain, deploy_contract, token, escrow, policy_manager):
|
||||
proxy, _ = deploy_contract('StakingInterfaceMockV2', token.address, escrow.address, policy_manager.address)
|
||||
secret = os.urandom(32)
|
||||
secret_hash = keccak(secret)
|
||||
router, _ = deploy_contract('StakingInterfaceRouter', proxy.address, secret_hash)
|
||||
def test_reentrancy(testerchain, preallocation_escrow, deploy_contract):
|
||||
owner = testerchain.client.accounts[1]
|
||||
|
||||
# Prepare contracts
|
||||
reentrancy_contract, _ = deploy_contract('ReentrancyTest')
|
||||
contract_address = reentrancy_contract.address
|
||||
preallocation_escrow, _ = deploy_contract('PreallocationEscrow', router.address, token.address, escrow.address)
|
||||
tx = preallocation_escrow.functions.transferOwnership(contract_address).transact()
|
||||
tx = preallocation_escrow.functions.transferOwnership(contract_address).transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Transfer ETH to user escrow
|
||||
|
@ -438,3 +437,168 @@ def test_reentrancy(testerchain, deploy_contract, token, escrow, policy_manager)
|
|||
tx = testerchain.client.send_transaction({'to': contract_address})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert testerchain.w3.eth.getBalance(contract_address) == balance
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_worklock(testerchain, worklock, preallocation_escrow, preallocation_escrow_interface, staking_interface):
|
||||
"""
|
||||
Test worklock functions in the preallocation escrow
|
||||
"""
|
||||
creator = testerchain.client.accounts[0]
|
||||
owner = testerchain.client.accounts[1]
|
||||
|
||||
bids = preallocation_escrow_interface.events.Bid.createFilter(fromBlock='latest')
|
||||
claims = preallocation_escrow_interface.events.Claimed.createFilter(fromBlock='latest')
|
||||
refunds = preallocation_escrow_interface.events.Refund.createFilter(fromBlock='latest')
|
||||
cancellations = preallocation_escrow_interface.events.BidCanceled.createFilter(fromBlock='latest')
|
||||
compensations = preallocation_escrow_interface.events.CompensationWithdrawn.createFilter(fromBlock='latest')
|
||||
|
||||
# Owner can't use the staking interface directly
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = staking_interface.functions.bid(0).transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = staking_interface.functions.cancelBid().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = staking_interface.functions.withdrawCompensation().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = staking_interface.functions.claim().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = staking_interface.functions.refund().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Send ETH to to the escrow
|
||||
bid = 10000
|
||||
tx = testerchain.client.send_transaction(
|
||||
{'from': testerchain.client.coinbase, 'to': preallocation_escrow.address, 'value': 2 * bid})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Bid
|
||||
assert worklock.functions.depositedETH().call() == 0
|
||||
assert testerchain.client.get_balance(preallocation_escrow.address) == 2 * bid
|
||||
tx = preallocation_escrow_interface.functions.bid(bid).transact({'from': owner, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.depositedETH().call() == bid
|
||||
assert testerchain.client.get_balance(preallocation_escrow.address) == bid
|
||||
|
||||
events = bids.get_all_entries()
|
||||
assert len(events) == 1
|
||||
event_args = events[0]['args']
|
||||
assert event_args['sender'] == owner
|
||||
assert event_args['depositedETH'] == bid
|
||||
|
||||
# Cancel bid
|
||||
tx = preallocation_escrow_interface.functions.cancelBid().transact({'from': owner, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.depositedETH().call() == 0
|
||||
assert testerchain.client.get_balance(preallocation_escrow.address) == 2 * bid
|
||||
|
||||
events = cancellations.get_all_entries()
|
||||
assert len(events) == 1
|
||||
event_args = events[0]['args']
|
||||
assert event_args['sender'] == owner
|
||||
|
||||
# Withdraw compensation
|
||||
compensation = 11000
|
||||
tx = worklock.functions.sendCompensation().transact({'from': creator, 'value': compensation, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.compensation().call() == compensation
|
||||
tx = preallocation_escrow_interface.functions.withdrawCompensation().transact({'from': owner, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.compensation().call() == 0
|
||||
assert testerchain.client.get_balance(preallocation_escrow.address) == 2 * bid + compensation
|
||||
|
||||
events = compensations.get_all_entries()
|
||||
assert len(events) == 1
|
||||
event_args = events[0]['args']
|
||||
assert event_args['sender'] == owner
|
||||
|
||||
# Claim
|
||||
assert worklock.functions.claimed().call() == 0
|
||||
tx = preallocation_escrow_interface.functions.claim().transact({'from': owner, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.claimed().call() == 1
|
||||
|
||||
events = claims.get_all_entries()
|
||||
assert len(events) == 1
|
||||
event_args = events[0]['args']
|
||||
assert event_args['sender'] == owner
|
||||
assert event_args['claimedTokens'] == 1
|
||||
|
||||
# Withdraw refund
|
||||
refund = 12000
|
||||
tx = worklock.functions.sendRefund().transact({'from': creator, 'value': refund, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.refundETH().call() == refund
|
||||
tx = preallocation_escrow_interface.functions.refund().transact({'from': owner, 'gas_price': 0})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
assert worklock.functions.refundETH().call() == 0
|
||||
assert testerchain.client.get_balance(preallocation_escrow.address) == 2 * bid + compensation + refund
|
||||
|
||||
events = refunds.get_all_entries()
|
||||
assert len(events) == 1
|
||||
event_args = events[0]['args']
|
||||
assert event_args['sender'] == owner
|
||||
assert event_args['refundETH'] == refund
|
||||
|
||||
|
||||
@pytest.mark.slow
|
||||
def test_interface_without_worklock(testerchain, deploy_contract, token, escrow, policy_manager, worklock):
|
||||
creator = testerchain.client.accounts[0]
|
||||
owner = testerchain.client.accounts[1]
|
||||
|
||||
staking_interface, _ = deploy_contract(
|
||||
'StakingInterface', token.address, escrow.address, policy_manager.address, worklock.address)
|
||||
secret = os.urandom(32)
|
||||
secret_hash = keccak(secret)
|
||||
router, _ = deploy_contract('StakingInterfaceRouter', staking_interface.address, secret_hash)
|
||||
|
||||
preallocation_escrow, _ = deploy_contract('PreallocationEscrow', router.address, token.address, escrow.address)
|
||||
# Transfer ownership
|
||||
tx = preallocation_escrow.functions.transferOwnership(owner).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
preallocation_escrow_interface = testerchain.client.get_contract(
|
||||
abi=staking_interface.abi,
|
||||
address=preallocation_escrow.address,
|
||||
ContractFactoryClass=Contract)
|
||||
|
||||
# All worklock methods work
|
||||
tx = preallocation_escrow_interface.functions.bid(0).transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = preallocation_escrow_interface.functions.cancelBid().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = preallocation_escrow_interface.functions.withdrawCompensation().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = preallocation_escrow_interface.functions.claim().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
tx = preallocation_escrow_interface.functions.refund().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Test interface without worklock
|
||||
secret2 = os.urandom(32)
|
||||
secret2_hash = keccak(secret2)
|
||||
staking_interface, _ = deploy_contract(
|
||||
'StakingInterface', token.address, escrow.address, policy_manager.address, BlockchainInterface.NULL_ADDRESS)
|
||||
tx = router.functions.upgrade(staking_interface.address, secret, secret2_hash).transact({'from': creator})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
||||
# Current version of interface doesn't have worklock contract
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = preallocation_escrow_interface.functions.bid(0).transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = preallocation_escrow_interface.functions.cancelBid().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = preallocation_escrow_interface.functions.withdrawCompensation().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = preallocation_escrow_interface.functions.claim().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
with pytest.raises((TransactionFailed, ValueError)):
|
||||
tx = preallocation_escrow_interface.functions.refund().transact({'from': owner})
|
||||
testerchain.wait_for_receipt(tx)
|
||||
|
|
Loading…
Reference in New Issue