Implemented staking logic and ZRX vault
This commit is contained in:
0
contracts/staking/contracts/src/MixinEpoch.sol
Normal file
0
contracts/staking/contracts/src/MixinEpoch.sol
Normal file
0
contracts/staking/contracts/src/MixinRewards.sol
Normal file
0
contracts/staking/contracts/src/MixinRewards.sol
Normal file
94
contracts/staking/contracts/src/MixinStake.sol
Normal file
94
contracts/staking/contracts/src/MixinStake.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 "./interfaces/IStake.sol";
|
||||
import "./mixins/MStake.sol";
|
||||
import "./interfaces/IVault.sol";
|
||||
import "./libs/LibZrxToken.sol";
|
||||
import "@0x/contracts-utils/contracts/src/SafeMath.sol";
|
||||
|
||||
|
||||
contract MixinStake is
|
||||
MStake,
|
||||
IStake,
|
||||
SafeMath
|
||||
{
|
||||
using LibZrxToken for uint256;
|
||||
|
||||
// default maker id that stake is delegated to
|
||||
bytes32 constant internal NIL_MAKER_ID = 0x0;
|
||||
|
||||
// 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;
|
||||
|
||||
// ZRX vault
|
||||
IVault zrxVault;
|
||||
|
||||
constructor(address _zrxVault) public {
|
||||
zrxVault = IVault(_zrxVault);
|
||||
}
|
||||
|
||||
function stake(uint256 amount)
|
||||
external
|
||||
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);
|
||||
|
||||
// return amount of stake minted
|
||||
return amountOfStakeToMint;
|
||||
}
|
||||
|
||||
function unstake(uint256 amount)
|
||||
external
|
||||
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);
|
||||
|
||||
// return amount of stake minted
|
||||
return amountOfStakeToBurn;
|
||||
}
|
||||
|
||||
function getStakeBalance(address owner)
|
||||
external
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return totalStake[owner];
|
||||
}
|
||||
}
|
0
contracts/staking/contracts/src/MixinTimelock.sol
Normal file
0
contracts/staking/contracts/src/MixinTimelock.sol
Normal file
@@ -18,9 +18,15 @@
|
||||
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
import "./IStaking.sol";
|
||||
import "./MixinStake.sol";
|
||||
|
||||
|
||||
contract Staking is IStaking {
|
||||
contract Staking is
|
||||
MixinStake
|
||||
{
|
||||
constructor(address zrxVault)
|
||||
public
|
||||
MixinStake(zrxVault)
|
||||
{}
|
||||
|
||||
}
|
||||
|
42
contracts/staking/contracts/src/interfaces/IAssetProxy.sol
Normal file
42
contracts/staking/contracts/src/interfaces/IAssetProxy.sol
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
|
||||
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 IAssetProxy {
|
||||
/// @dev Transfers assets. Either succeeds or throws.
|
||||
/// @param assetData Byte array encoded for the respective asset proxy.
|
||||
/// @param from Address to transfer asset from.
|
||||
/// @param to Address to transfer asset to.
|
||||
/// @param amount Amount of asset to transfer.
|
||||
function transferFrom(
|
||||
bytes calldata assetData,
|
||||
address from,
|
||||
address to,
|
||||
uint256 amount
|
||||
)
|
||||
external;
|
||||
|
||||
/// @dev Gets the proxy id associated with the proxy address.
|
||||
/// @return Proxy id.
|
||||
function getProxyId()
|
||||
external
|
||||
pure
|
||||
returns (bytes4);
|
||||
}
|
27
contracts/staking/contracts/src/interfaces/IStake.sol
Normal file
27
contracts/staking/contracts/src/interfaces/IStake.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;
|
||||
|
||||
|
||||
contract IStake
|
||||
{
|
||||
function stake(uint256 amount) external returns (uint256);
|
||||
function unstake(uint256 amount) external returns (uint256);
|
||||
function getStakeBalance(address owner) external view returns (uint256);
|
||||
}
|
31
contracts/staking/contracts/src/interfaces/IVault.sol
Normal file
31
contracts/staking/contracts/src/interfaces/IVault.sol
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
|
||||
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 IVault {
|
||||
|
||||
function depositFrom(address owner, uint256 amount) external;
|
||||
|
||||
function withdrawFrom(address owner, uint256 amount) external;
|
||||
|
||||
function withdrawAllFrom(address owner) external returns (uint256);
|
||||
|
||||
function balanceOf(address owner) external view returns (uint256);
|
||||
}
|
33
contracts/staking/contracts/src/libs/LibZrxToken.sol
Normal file
33
contracts/staking/contracts/src/libs/LibZrxToken.sol
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
|
||||
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;
|
||||
|
||||
|
||||
library LibZrxToken {
|
||||
|
||||
uint256 constant internal TOKEN_MULTIPLIER = 10**18;
|
||||
|
||||
function roundDownToNearestWholeToken(uint256 value)
|
||||
public
|
||||
pure
|
||||
returns (uint256)
|
||||
{
|
||||
return (value / TOKEN_MULTIPLIER) * TOKEN_MULTIPLIER;
|
||||
}
|
||||
}
|
@@ -19,6 +19,8 @@
|
||||
pragma solidity ^0.5.9;
|
||||
|
||||
|
||||
interface IStaking {
|
||||
contract MStake
|
||||
{
|
||||
|
||||
|
||||
}
|
66
contracts/staking/contracts/src/vaults/MixinVaultCore.sol
Normal file
66
contracts/staking/contracts/src/vaults/MixinVaultCore.sol
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
|
||||
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 "@0x/contracts-utils/contracts/src/Authorizable.sol";
|
||||
|
||||
|
||||
contract MixinVaultCore is
|
||||
Authorizable
|
||||
{
|
||||
|
||||
address internal stakingContractAddress;
|
||||
|
||||
bool internal isInCatostrophicFailure;
|
||||
|
||||
constructor(address _stakingContractAddress) public {
|
||||
stakingContractAddress = _stakingContractAddress;
|
||||
isInCatostrophicFailure = false;
|
||||
}
|
||||
|
||||
modifier onlyStakingContract {
|
||||
require(
|
||||
msg.sender == stakingContractAddress,
|
||||
"ONLY_CALLABLE_BY_STAKING_CONTRACT"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlyInCatostrophicFailure {
|
||||
require(
|
||||
isInCatostrophicFailure,
|
||||
"ONLY_CALLABLE_IN_CATOSTROPHIC_FAILURE"
|
||||
);
|
||||
_;
|
||||
}
|
||||
|
||||
function setStakingContractAddrsess(address _stakingContractAddress)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
stakingContractAddress = _stakingContractAddress;
|
||||
}
|
||||
|
||||
function enterCatostrophicFailure()
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
isInCatostrophicFailure = true;
|
||||
}
|
||||
}
|
119
contracts/staking/contracts/src/vaults/ZrxVault.sol
Normal file
119
contracts/staking/contracts/src/vaults/ZrxVault.sol
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
|
||||
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 "../interfaces/IAssetProxy.sol";
|
||||
import "@0x/contracts-utils/contracts/src/SafeMath.sol";
|
||||
import "./MixinVaultCore.sol";
|
||||
|
||||
|
||||
contract ZrxVault is
|
||||
IVault,
|
||||
SafeMath,
|
||||
MixinVaultCore
|
||||
{
|
||||
|
||||
// mapping from Owner to ZRX balance
|
||||
mapping (address => uint256) internal balances;
|
||||
|
||||
IAssetProxy internal erc20Proxy;
|
||||
|
||||
bytes internal zrxAssetData;
|
||||
|
||||
constructor(address _erc20ProxyAddress, bytes memory _zrxAssetData) public {
|
||||
erc20Proxy = IAssetProxy(_erc20ProxyAddress);
|
||||
zrxAssetData = _zrxAssetData;
|
||||
}
|
||||
|
||||
function setErc20Proxy(address _erc20ProxyAddress)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
erc20Proxy = IAssetProxy(_erc20ProxyAddress);
|
||||
}
|
||||
|
||||
function setZrxAssetData(bytes calldata _zrxAssetData)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
zrxAssetData = _zrxAssetData;
|
||||
}
|
||||
|
||||
function depositFrom(address owner, uint256 amount)
|
||||
external
|
||||
onlyStakingContract
|
||||
{
|
||||
// deposit ZRX from owner
|
||||
erc20Proxy.transferFrom(
|
||||
zrxAssetData,
|
||||
address(this),
|
||||
owner,
|
||||
amount
|
||||
);
|
||||
|
||||
// update balance
|
||||
balances[owner] = _safeAdd(balances[owner], amount);
|
||||
}
|
||||
|
||||
function withdrawFrom(address owner, uint256 amount)
|
||||
external
|
||||
onlyStakingContract
|
||||
{
|
||||
_withdrawFrom(owner, amount);
|
||||
}
|
||||
|
||||
function withdrawAllFrom(address owner)
|
||||
external
|
||||
onlyInCatostrophicFailure
|
||||
returns (uint256)
|
||||
{
|
||||
// get total balance
|
||||
uint256 totalBalance = balances[owner];
|
||||
|
||||
// withdraw ZRX to owner
|
||||
_withdrawFrom(owner, totalBalance);
|
||||
return totalBalance;
|
||||
}
|
||||
|
||||
function _withdrawFrom(address owner, uint256 amount)
|
||||
internal
|
||||
{
|
||||
// withdraw ZRX to owner
|
||||
erc20Proxy.transferFrom(
|
||||
zrxAssetData,
|
||||
address(this),
|
||||
owner,
|
||||
amount
|
||||
);
|
||||
|
||||
// update balance
|
||||
// note that this call will revert if trying to withdraw more
|
||||
// than the current balance
|
||||
balances[owner] = _safeSub(balances[owner], amount);
|
||||
}
|
||||
|
||||
function balanceOf(address owner)
|
||||
external
|
||||
view
|
||||
returns (uint256)
|
||||
{
|
||||
return balances[owner];
|
||||
}
|
||||
}
|
@@ -35,7 +35,7 @@
|
||||
"compile:truffle": "truffle compile"
|
||||
},
|
||||
"config": {
|
||||
"abis": "./generated-artifacts/@(IStaking|Staking).json",
|
||||
"abis": "./generated-artifacts/@(LibZrxToken|MixinStake|MixinVaultCore|Staking|ZrxVault).json",
|
||||
"abis:comment": "This list is auto-generated by contracts-gen. Don't edit manually."
|
||||
},
|
||||
"repository": {
|
||||
|
@@ -5,6 +5,15 @@
|
||||
*/
|
||||
import { ContractArtifact } from 'ethereum-types';
|
||||
|
||||
import * as IStaking from '../generated-artifacts/IStaking.json';
|
||||
import * as LibZrxToken from '../generated-artifacts/LibZrxToken.json';
|
||||
import * as MixinStake from '../generated-artifacts/MixinStake.json';
|
||||
import * as MixinVaultCore from '../generated-artifacts/MixinVaultCore.json';
|
||||
import * as Staking from '../generated-artifacts/Staking.json';
|
||||
export const artifacts = { IStaking: IStaking as ContractArtifact, Staking: Staking as ContractArtifact };
|
||||
import * as ZrxVault from '../generated-artifacts/ZrxVault.json';
|
||||
export const artifacts = {
|
||||
MixinStake: MixinStake as ContractArtifact,
|
||||
Staking: Staking as ContractArtifact,
|
||||
LibZrxToken: LibZrxToken as ContractArtifact,
|
||||
MixinVaultCore: MixinVaultCore as ContractArtifact,
|
||||
ZrxVault: ZrxVault as ContractArtifact,
|
||||
};
|
||||
|
@@ -3,5 +3,8 @@
|
||||
* Warning: This file is auto-generated by contracts-gen. Don't edit manually.
|
||||
* -----------------------------------------------------------------------------
|
||||
*/
|
||||
export * from '../generated-wrappers/i_staking';
|
||||
export * from '../generated-wrappers/lib_zrx_token';
|
||||
export * from '../generated-wrappers/mixin_stake';
|
||||
export * from '../generated-wrappers/mixin_vault_core';
|
||||
export * from '../generated-wrappers/staking';
|
||||
export * from '../generated-wrappers/zrx_vault';
|
||||
|
@@ -2,6 +2,12 @@
|
||||
"extends": "../../tsconfig",
|
||||
"compilerOptions": { "outDir": "lib", "rootDir": ".", "resolveJsonModule": true },
|
||||
"include": ["./src/**/*", "./test/**/*", "./generated-wrappers/**/*"],
|
||||
"files": ["generated-artifacts/IStaking.json", "generated-artifacts/Staking.json"],
|
||||
"files": [
|
||||
"generated-artifacts/LibZrxToken.json",
|
||||
"generated-artifacts/MixinStake.json",
|
||||
"generated-artifacts/MixinVaultCore.json",
|
||||
"generated-artifacts/Staking.json",
|
||||
"generated-artifacts/ZrxVault.json"
|
||||
],
|
||||
"exclude": ["./deploy/solc/solc_bin"]
|
||||
}
|
||||
|
Reference in New Issue
Block a user