Split Storage Logic + Staking Logic Contracts
This commit is contained in:
94
contracts/staking/contracts/src/StakingProxy.sol
Normal file
94
contracts/staking/contracts/src/StakingProxy.sol
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
import "./core/MixinStorage.sol";
|
||||
import "./interfaces/IStakingProxy.sol";
|
||||
|
||||
|
||||
contract StakingProxy is
|
||||
IStakingProxy,
|
||||
MixinStorage
|
||||
{
|
||||
address constant NIL_ADDRESS = 0x0000000000000000000000000000000000000000;
|
||||
|
||||
constructor(address _stakingContract)
|
||||
public
|
||||
{
|
||||
stakingContract = _stakingContract;
|
||||
}
|
||||
|
||||
function ()
|
||||
external
|
||||
payable
|
||||
{
|
||||
address _stakingContract = stakingContract;
|
||||
if (_stakingContract == NIL_ADDRESS) {
|
||||
return;
|
||||
}
|
||||
|
||||
assembly {
|
||||
// copy calldata to memory
|
||||
calldatacopy(
|
||||
0x0,
|
||||
0x0,
|
||||
calldatasize()
|
||||
)
|
||||
|
||||
// delegate call into staking contract
|
||||
let success := delegatecall(
|
||||
gas, // forward all gas
|
||||
_stakingContract, // calling staking contract
|
||||
0x0, // start of input (calldata)
|
||||
calldatasize(), // length of input (calldata)
|
||||
0x0, // write output over input
|
||||
0 // length of output is unknown
|
||||
)
|
||||
|
||||
// copy return data to memory
|
||||
returndatacopy(
|
||||
0x0,
|
||||
0x0,
|
||||
returndatasize()
|
||||
)
|
||||
|
||||
// rethrow any exceptions
|
||||
if iszero(success) {
|
||||
revert(0, returndatasize())
|
||||
}
|
||||
|
||||
// return call results
|
||||
return(0, returndatasize())
|
||||
}
|
||||
}
|
||||
|
||||
function attachStakingContract(address _stakingContract)
|
||||
external
|
||||
//ownerOnly
|
||||
{
|
||||
stakingContract = _stakingContract;
|
||||
}
|
||||
|
||||
function detachStakingContract()
|
||||
external
|
||||
//ownerOnly
|
||||
{
|
||||
stakingContract = NIL_ADDRESS;
|
||||
}
|
||||
}
|
||||
0
contracts/staking/contracts/src/core/MixinEpoch.sol
Normal file
0
contracts/staking/contracts/src/core/MixinEpoch.sol
Normal file
153
contracts/staking/contracts/src/core/MixinStake.sol
Normal file
153
contracts/staking/contracts/src/core/MixinStake.sol
Normal file
@@ -0,0 +1,153 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
import "../interfaces/IVault.sol";
|
||||
import "../libs/LibZrxToken.sol";
|
||||
import "@0x/contracts-utils/contracts/src/SafeMath.sol";
|
||||
import "./MixinStorage.sol";
|
||||
import "../interfaces/IStakingEvents.sol";
|
||||
|
||||
|
||||
contract MixinStake is
|
||||
SafeMath,
|
||||
IStakingEvents,
|
||||
MixinStorage
|
||||
{
|
||||
using LibZrxToken for uint256;
|
||||
|
||||
// default maker id that stake is delegated to
|
||||
bytes32 constant internal NIL_MAKER_ID = 0x0;
|
||||
|
||||
function _stake(uint256 amount)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
// sanitize input - can only stake whole tokens
|
||||
uint256 amountOfStakeToMint = amount._roundDownToNearestWholeToken();
|
||||
|
||||
// deposit equivalent amount of ZRX into vault
|
||||
zrxVault.depositFrom(msg.sender, amountOfStakeToMint);
|
||||
|
||||
// mint stake
|
||||
totalStake[msg.sender] = _safeAdd(totalStake[msg.sender], amountOfStakeToMint);
|
||||
delegatedStake[msg.sender][NIL_MAKER_ID] = _safeAdd(delegatedStake[msg.sender][NIL_MAKER_ID], amountOfStakeToMint);
|
||||
|
||||
// emit stake event
|
||||
emit StakeMinted(
|
||||
msg.sender,
|
||||
amountOfStakeToMint
|
||||
);
|
||||
|
||||
// return amount of stake minted
|
||||
return amountOfStakeToMint;
|
||||
}
|
||||
|
||||
function _unstake(uint256 amount)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
// sanitize input - can only stake whole tokens
|
||||
uint256 amountOfStakeToBurn = amount._roundDownToNearestWholeToken();
|
||||
|
||||
// burn stake
|
||||
totalStake[msg.sender] = _safeSub(totalStake[msg.sender], amountOfStakeToBurn);
|
||||
delegatedStake[msg.sender][NIL_MAKER_ID] = _safeSub(delegatedStake[msg.sender][NIL_MAKER_ID], amountOfStakeToBurn);
|
||||
|
||||
// withdraw equivalent amount of ZRX from vault
|
||||
zrxVault.withdrawFrom(msg.sender, amountOfStakeToBurn);
|
||||
|
||||
// emit stake event
|
||||
emit StakeMinted(
|
||||
msg.sender,
|
||||
amountOfStakeToBurn
|
||||
);
|
||||
|
||||
// return amount of stake minted
|
||||
return amountOfStakeToBurn;
|
||||
}
|
||||
|
||||
function _delegateStake(bytes32 makerId, uint256 amount)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
uint256 amountOfStakeToDelegate = amount._roundDownToNearestWholeToken();
|
||||
}
|
||||
|
||||
// returns
|
||||
function _undelegateStake(bytes32 makerId, uint256 amount)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
function _undelegateStake(bytes32 makerId)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
address owner = msg.sender;
|
||||
uint256 delegatedStakeBalance = _getStakeDelegatedByOwner(owner, makerId);
|
||||
_undelegateStake(makerId, delegatedStakeBalance);
|
||||
}
|
||||
|
||||
function _stakeAndDelegate(bytes32 makerId, uint256 amount)
|
||||
internal
|
||||
returns (uint256 amountOfStakeDelegated)
|
||||
{
|
||||
// mint stake
|
||||
uint256 amountOfStakeMinted = _stake(amount);
|
||||
|
||||
// delegate stake to maker
|
||||
amountOfStakeDelegated = _delegateStake(makerId, amountOfStakeMinted);
|
||||
return amountOfStakeDelegated;
|
||||
}
|
||||
|
||||
function _getStakeDelegatedByOwner(address owner, bytes32 makerId)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
return delegatedStake[owner][makerId];
|
||||
}
|
||||
|
||||
function _getTotalStakeDelegatedByOwner(address owner)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
return _safeSub(
|
||||
totalStake[owner],
|
||||
delegatedStake[owner][NIL_MAKER_ID]
|
||||
);
|
||||
}
|
||||
|
||||
function _getTotalStakeDelegatedToMaker(bytes32 makerId)
|
||||
internal
|
||||
returns (uint256)
|
||||
{
|
||||
return totalDelegatedStake[makerId];
|
||||
}
|
||||
|
||||
function _getStakeBalance(address owner)
|
||||
internal
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return totalStake[owner];
|
||||
}
|
||||
}
|
||||
43
contracts/staking/contracts/src/core/MixinStorage.sol
Normal file
43
contracts/staking/contracts/src/core/MixinStorage.sol
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
import "../interfaces/IVault.sol";
|
||||
|
||||
|
||||
contract MixinStorage {
|
||||
|
||||
// address of staking contract
|
||||
address stakingContract;
|
||||
|
||||
// mapping from Staker to Maker Id to Amount Staked
|
||||
mapping (address => mapping (bytes32 => uint256)) delegatedStake;
|
||||
|
||||
// mapping from Staker to Maker Id to Amount Staked
|
||||
mapping (address => uint256) totalStake;
|
||||
|
||||
// mapping from Maker Id to Amount of Delegated Staked
|
||||
mapping (bytes32 => uint256) totalDelegatedStake;
|
||||
|
||||
// ZRX vault
|
||||
IVault zrxVault;
|
||||
|
||||
// Rebate Vault
|
||||
IVault rebateVault;
|
||||
}
|
||||
27
contracts/staking/contracts/src/interfaces/IStaking.sol
Normal file
27
contracts/staking/contracts/src/interfaces/IStaking.sol
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
|
||||
interface IStaking
|
||||
{
|
||||
function stake(uint256 amount) external returns (uint256);
|
||||
function unstake(uint256 amount) external returns (uint256);
|
||||
function getStakeBalance(address owner) external view returns (uint256);
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
|
||||
|
||||
interface IStakingEvents {
|
||||
|
||||
event StakeMinted(
|
||||
address owner,
|
||||
uint256 amount
|
||||
);
|
||||
|
||||
event StakeBurned(
|
||||
address owner,
|
||||
uint256 amount
|
||||
);
|
||||
}
|
||||
27
contracts/staking/contracts/src/interfaces/IStakingProxy.sol
Normal file
27
contracts/staking/contracts/src/interfaces/IStakingProxy.sol
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
|
||||
interface IStakingProxy
|
||||
{
|
||||
/*function attachStakingContract(address stakingContract) external;
|
||||
function detachStakingContract() external;
|
||||
function () external payable;*/
|
||||
}
|
||||
24
contracts/staking/contracts/src/registries/MakerRegistry.sol
Normal file
24
contracts/staking/contracts/src/registries/MakerRegistry.sol
Normal file
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
|
||||
Copyright 2018 ZeroEx Intl.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
*/
|
||||
|
||||
pragma solidity ^0.5.5;
|
||||
|
||||
|
||||
contract MakerRegistry {
|
||||
|
||||
}
|
||||
@@ -93,7 +93,7 @@ export class StakingWrapper {
|
||||
txDefaults,
|
||||
);
|
||||
}
|
||||
private async _executeTransaction(calldata: string, from: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
private async _executeTransactionAsync(calldata: string, from: string): Promise<TransactionReceiptWithDecodedLogs> {
|
||||
const txData = {
|
||||
from,
|
||||
to: this.getStakingProxyContract().address,
|
||||
@@ -105,20 +105,33 @@ export class StakingWrapper {
|
||||
);
|
||||
return txReceipt;
|
||||
}
|
||||
private async _callAsync(calldata: string, from: string): Promise<any> {
|
||||
const txData = {
|
||||
from,
|
||||
to: this.getStakingProxyContract().address,
|
||||
data: calldata,
|
||||
gas: 3000000
|
||||
}
|
||||
const returnValue = await this._web3Wrapper.callAsync(txData);
|
||||
return returnValue;
|
||||
}
|
||||
public async stake(holder: string, amount: BigNumber): Promise<BigNumber> {
|
||||
const calldata = await this.getStakingContract().stake.getABIEncodedTransactionData(amount);
|
||||
const txReceipt = await this._executeTransaction(calldata, holder);
|
||||
const calldata = this.getStakingContract().stake.getABIEncodedTransactionData(amount);
|
||||
const txReceipt = await this._executeTransactionAsync(calldata, holder);
|
||||
const stakeMintedLog = this._logDecoder.decodeLogOrThrow(txReceipt.logs[1]);
|
||||
const stakeMinted = (stakeMintedLog as any).args.amount;
|
||||
return stakeMinted;
|
||||
}
|
||||
public async unstake(holder: string, amount: BigNumber): Promise<BigNumber> {
|
||||
const stakeBurned = await this.getStakingContract().unstake.callAsync(amount, {from: holder});
|
||||
await this.getStakingContract().unstake.awaitTransactionSuccessAsync(amount, {from: holder});
|
||||
const calldata = this.getStakingContract().unstake.getABIEncodedTransactionData(amount);
|
||||
const txReceipt = await this._executeTransactionAsync(calldata, holder);
|
||||
const stakeBurnedLog = this._logDecoder.decodeLogOrThrow(txReceipt.logs[1]);
|
||||
const stakeBurned = (stakeBurnedLog as any).args.amount;
|
||||
return stakeBurned;
|
||||
}
|
||||
public async getStakeBalance(holder: string): Promise<BigNumber> {
|
||||
const balance = await this.getStakingContract().getStakeBalance.callAsync(holder);
|
||||
const calldata = this.getStakingContract().getStakeBalance.getABIEncodedTransactionData(holder);
|
||||
const balance = await this._callAsync(calldata, holder);
|
||||
return balance;
|
||||
}
|
||||
public async getZrxVaultBalance(holder: string): Promise<BigNumber> {
|
||||
|
||||
Reference in New Issue
Block a user