文件 1 的 1:StakingPools.sol
pragma solidity >=0.4.22 <0.8.0;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
function pow(uint256 base, uint256 exponent) internal pure returns (uint256) {
if (exponent == 0) {
return 1;
}
else if (exponent == 1) {
return base;
}
else if (base == 0 && exponent != 0) {
return 0;
}
else {
uint256 z = base;
for (uint256 i = 1; i < exponent; i++)
z = mul(z, base);
return z;
}
}
}
library FixedPointMath {
uint256 public constant DECIMALS = 18;
uint256 public constant SCALAR = 10**DECIMALS;
struct FixedDecimal {
uint256 x;
}
function fromU256(uint256 value) internal pure returns (FixedDecimal memory) {
uint256 x;
require(value == 0 || (x = value * SCALAR) / SCALAR == value);
return FixedDecimal(x);
}
function maximumValue() internal pure returns (FixedDecimal memory) {
return FixedDecimal(uint256(-1));
}
function add(FixedDecimal memory self, FixedDecimal memory value) internal pure returns (FixedDecimal memory) {
uint256 x;
require((x = self.x + value.x) >= self.x);
return FixedDecimal(x);
}
function add(FixedDecimal memory self, uint256 value) internal pure returns (FixedDecimal memory) {
return add(self, fromU256(value));
}
function sub(FixedDecimal memory self, FixedDecimal memory value) internal pure returns (FixedDecimal memory) {
uint256 x;
require((x = self.x - value.x) <= self.x);
return FixedDecimal(x);
}
function sub(FixedDecimal memory self, uint256 value) internal pure returns (FixedDecimal memory) {
return sub(self, fromU256(value));
}
function mul(FixedDecimal memory self, uint256 value) internal pure returns (FixedDecimal memory) {
uint256 x;
require(value == 0 || (x = self.x * value) / value == self.x);
return FixedDecimal(x);
}
function div(FixedDecimal memory self, uint256 value) internal pure returns (FixedDecimal memory) {
require(value != 0);
return FixedDecimal(self.x / value);
}
function cmp(FixedDecimal memory self, FixedDecimal memory value) internal pure returns (int256) {
if (self.x < value.x) {
return -1;
}
if (self.x > value.x) {
return 1;
}
return 0;
}
function decode(FixedDecimal memory self) internal pure returns (uint256) {
return self.x / SCALAR;
}
}
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
contract Context {
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this;
return msg.data;
}
}
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
function transferOwnership(address newOwner) public onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
contract Accessible is Ownable {
mapping(address => bool) private access;
constructor() {
access[msg.sender] = true;
}
modifier hasAccess() {
require(checkAccess(msg.sender));
_;
}
function checkAccess(address sender) public view returns (bool) {
if (access[sender] == true)
return true;
return false;
}
function removeAccess(address addr) public hasAccess returns (bool success) {
access[addr] = false;
return true;
}
function addAccess(address addr) public hasAccess returns (bool) {
access[addr] = true;
return true;
}
}
contract ExternalAccessible {
address public accessContract;
function checkAccess(address sender) public returns (bool) {
bool result = Accessible(accessContract).checkAccess(sender);
require(result == true);
return true;
}
modifier hasAccess() {
require(checkAccess(msg.sender));
_;
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
abstract contract ERC20 is Context, IERC20, ExternalAccessible {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string public _name;
string public _symbol;
uint8 public _decimals;
function name() public view returns (string memory) {
return _name;
}
function symbol() public view returns (string memory) {
return _symbol;
}
function decimals() public view returns (uint8) {
return _decimals;
}
function totalSupply() public view override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) external virtual hasAccess {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) external virtual hasAccess {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _setupDecimals(uint8 decimals_) internal {
_decimals = decimals_;
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}
contract wXEQ is ERC20 {
constructor(address _accessContract) {
_name = "Wrapped Equilibria v2";
_symbol = "wXEQ";
_decimals = 18;
accessContract = _accessContract;
}
}
contract ReentrancyGuard {
bool private rentrancy_lock = false;
modifier nonReentrant() {
require(!rentrancy_lock);
rentrancy_lock = true;
_;
rentrancy_lock = false;
}
}
library Pool {
using FixedPointMath for FixedPointMath.FixedDecimal;
using Pool for Pool.Data;
using Pool for Pool.List;
using SafeMath for uint256;
struct Context {
uint256 rewardRate;
uint256 totalRewardWeight;
}
struct Data {
IERC20 token;
uint256 totalDeposited;
uint256 rewardWeight;
FixedPointMath.FixedDecimal accumulatedRewardWeight;
uint256 lastUpdatedBlock;
}
struct List {
Data[] elements;
}
function update(Data storage _data, Context storage _ctx) internal {
_data.accumulatedRewardWeight = _data.getUpdatedAccumulatedRewardWeight(_ctx);
_data.lastUpdatedBlock = block.number;
}
function getRewardRate(Data storage _data, Context storage _ctx)
internal view
returns (uint256)
{
return _ctx.rewardRate.mul(_data.rewardWeight).div(_ctx.totalRewardWeight);
}
function getUpdatedAccumulatedRewardWeight(Data storage _data, Context storage _ctx)
internal view
returns (FixedPointMath.FixedDecimal memory)
{
if (_data.totalDeposited == 0) {
return _data.accumulatedRewardWeight;
}
uint256 _elapsedTime = block.number.sub(_data.lastUpdatedBlock);
if (_elapsedTime == 0) {
return _data.accumulatedRewardWeight;
}
uint256 _rewardRate = _data.getRewardRate(_ctx);
uint256 _distributeAmount = _rewardRate.mul(_elapsedTime);
if (_distributeAmount == 0) {
return _data.accumulatedRewardWeight;
}
FixedPointMath.FixedDecimal memory _rewardWeight = FixedPointMath.fromU256(_distributeAmount).div(_data.totalDeposited);
return _data.accumulatedRewardWeight.add(_rewardWeight);
}
function push(List storage _self, Data memory _element) internal {
_self.elements.push(_element);
}
function get(List storage _self, uint256 _index) internal view returns (Data storage) {
return _self.elements[_index];
}
function last(List storage _self) internal view returns (Data storage) {
return _self.elements[_self.lastIndex()];
}
function lastIndex(List storage _self) internal view returns (uint256) {
uint256 _length = _self.length();
return _length.sub(1, "Pool.List: list is empty");
}
function length(List storage _self) internal view returns (uint256) {
return _self.elements.length;
}
}
library Stake {
using FixedPointMath for FixedPointMath.FixedDecimal;
using Pool for Pool.Data;
using SafeMath for uint256;
using Stake for Stake.Data;
struct Data {
uint256 totalDeposited;
uint256 totalUnclaimed;
FixedPointMath.FixedDecimal lastAccumulatedWeight;
}
function update(Data storage _self, Pool.Data storage _pool, Pool.Context storage _ctx) internal {
_self.totalUnclaimed = _self.getUpdatedTotalUnclaimed(_pool, _ctx);
_self.lastAccumulatedWeight = _pool.getUpdatedAccumulatedRewardWeight(_ctx);
}
function getUpdatedTotalUnclaimed(Data storage _self, Pool.Data storage _pool, Pool.Context storage _ctx)
internal view
returns (uint256)
{
FixedPointMath.FixedDecimal memory _currentAccumulatedWeight = _pool.getUpdatedAccumulatedRewardWeight(_ctx);
FixedPointMath.FixedDecimal memory _lastAccumulatedWeight = _self.lastAccumulatedWeight;
if (_currentAccumulatedWeight.cmp(_lastAccumulatedWeight) == 0) {
return _self.totalUnclaimed;
}
uint256 _distributedAmount = _currentAccumulatedWeight
.sub(_lastAccumulatedWeight)
.mul(_self.totalDeposited)
.decode();
return _self.totalUnclaimed.add(_distributedAmount);
}
}
interface IDetailedERC20 is IERC20 {
function name() external returns (string memory);
function symbol() external returns (string memory);
function decimals() external returns (uint8);
}
interface IMintableERC20 is IDetailedERC20{
function _mint(address _recipient, uint256 _amount) external;
function _burn(address account, uint256 amount) external;
}
contract StakingPools is ReentrancyGuard {
using FixedPointMath for FixedPointMath.FixedDecimal;
using Pool for Pool.Data;
using Pool for Pool.List;
using SafeERC20 for IERC20;
using SafeMath for uint256;
using Stake for Stake.Data;
event PendingGovernanceUpdated(
address pendingGovernance
);
event GovernanceUpdated(
address governance
);
event RewardRateUpdated(
uint256 rewardRate
);
event PoolRewardWeightUpdated(
uint256 indexed poolId,
uint256 rewardWeight
);
event PoolCreated(
uint256 indexed poolId,
IERC20 indexed token
);
event TokensDeposited(
address indexed user,
uint256 indexed poolId,
uint256 amount
);
event TokensWithdrawn(
address indexed user,
uint256 indexed poolId,
uint256 amount
);
event TokensClaimed(
address indexed user,
uint256 indexed poolId,
uint256 amount
);
IMintableERC20 public reward;
address public governance;
address public pendingGovernance;
mapping(IERC20 => uint256) public tokenPoolIds;
Pool.Context private _ctx;
Pool.List private _pools;
mapping(address => mapping(uint256 => Stake.Data)) private _stakes;
uint256 public totalTokensClaimed;
constructor(
IMintableERC20 _reward,
address _governance
) public {
require(_governance != address(0), "StakingPools: governance address cannot be 0x0");
reward = _reward;
governance = _governance;
}
modifier onlyGovernance() {
require(msg.sender == governance, "StakingPools: only governance");
_;
}
function setPendingGovernance(address _pendingGovernance) external onlyGovernance {
require(_pendingGovernance != address(0), "StakingPools: pending governance address cannot be 0x0");
pendingGovernance = _pendingGovernance;
emit PendingGovernanceUpdated(_pendingGovernance);
}
function acceptGovernance() external {
require(msg.sender == pendingGovernance, "StakingPools: only pending governance");
address _pendingGovernance = pendingGovernance;
governance = _pendingGovernance;
emit GovernanceUpdated(_pendingGovernance);
}
function setRewardRate(uint256 _rewardRate) external onlyGovernance {
_updatePools();
_ctx.rewardRate = _rewardRate;
emit RewardRateUpdated(_rewardRate);
}
function createPool(IERC20 _token) external onlyGovernance returns (uint256) {
require(tokenPoolIds[_token] == 0, "StakingPools: token already has a pool");
uint256 _poolId = _pools.length();
_pools.push(Pool.Data({
token: _token,
totalDeposited: 0,
rewardWeight: 0,
accumulatedRewardWeight: FixedPointMath.FixedDecimal(0),
lastUpdatedBlock: block.number
}));
tokenPoolIds[_token] = _poolId + 1;
emit PoolCreated(_poolId, _token);
return _poolId;
}
function setRewardWeights(uint256[] calldata _rewardWeights) external onlyGovernance {
require(_rewardWeights.length == _pools.length(), "StakingPools: weights length mismatch");
_updatePools();
uint256 _totalRewardWeight = _ctx.totalRewardWeight;
for (uint256 _poolId = 0; _poolId < _pools.length(); _poolId++) {
Pool.Data storage _pool = _pools.get(_poolId);
uint256 _currentRewardWeight = _pool.rewardWeight;
if (_currentRewardWeight == _rewardWeights[_poolId]) {
continue;
}
_totalRewardWeight = _totalRewardWeight.sub(_currentRewardWeight).add(_rewardWeights[_poolId]);
_pool.rewardWeight = _rewardWeights[_poolId];
emit PoolRewardWeightUpdated(_poolId, _rewardWeights[_poolId]);
}
_ctx.totalRewardWeight = _totalRewardWeight;
}
function deposit(uint256 _poolId, uint256 _depositAmount) external nonReentrant {
Pool.Data storage _pool = _pools.get(_poolId);
_pool.update(_ctx);
Stake.Data storage _stake = _stakes[msg.sender][_poolId];
_stake.update(_pool, _ctx);
_deposit(_poolId, _depositAmount);
}
function withdraw(uint256 _poolId, uint256 _withdrawAmount) external nonReentrant {
Pool.Data storage _pool = _pools.get(_poolId);
_pool.update(_ctx);
Stake.Data storage _stake = _stakes[msg.sender][_poolId];
_stake.update(_pool, _ctx);
_claim(_poolId);
_withdraw(_poolId, _withdrawAmount);
}
function claim(uint256 _poolId) external nonReentrant {
Pool.Data storage _pool = _pools.get(_poolId);
_pool.update(_ctx);
Stake.Data storage _stake = _stakes[msg.sender][_poolId];
_stake.update(_pool, _ctx);
_claim(_poolId);
}
function exit(uint256 _poolId) external nonReentrant {
Pool.Data storage _pool = _pools.get(_poolId);
_pool.update(_ctx);
Stake.Data storage _stake = _stakes[msg.sender][_poolId];
_stake.update(_pool, _ctx);
_claim(_poolId);
_withdraw(_poolId, _stake.totalDeposited);
}
function rewardRate() external view returns (uint256) {
return _ctx.rewardRate;
}
function totalRewardWeight() external view returns (uint256) {
return _ctx.totalRewardWeight;
}
function poolCount() external view returns (uint256) {
return _pools.length();
}
function getPoolToken(uint256 _poolId) external view returns (IERC20) {
Pool.Data storage _pool = _pools.get(_poolId);
return _pool.token;
}
function getPoolTotalDeposited(uint256 _poolId) external view returns (uint256) {
Pool.Data storage _pool = _pools.get(_poolId);
return _pool.totalDeposited;
}
function getPoolRewardWeight(uint256 _poolId) external view returns (uint256) {
Pool.Data storage _pool = _pools.get(_poolId);
return _pool.rewardWeight;
}
function getPoolRewardRate(uint256 _poolId) external view returns (uint256) {
Pool.Data storage _pool = _pools.get(_poolId);
return _pool.getRewardRate(_ctx);
}
function getStakeTotalDeposited(address _account, uint256 _poolId) external view returns (uint256) {
Stake.Data storage _stake = _stakes[_account][_poolId];
return _stake.totalDeposited;
}
function getStakeTotalUnclaimed(address _account, uint256 _poolId) external view returns (uint256) {
Stake.Data storage _stake = _stakes[_account][_poolId];
return _stake.getUpdatedTotalUnclaimed(_pools.get(_poolId), _ctx);
}
function _updatePools() internal {
for (uint256 _poolId = 0; _poolId < _pools.length(); _poolId++) {
Pool.Data storage _pool = _pools.get(_poolId);
_pool.update(_ctx);
}
}
function _deposit(uint256 _poolId, uint256 _depositAmount) internal {
Pool.Data storage _pool = _pools.get(_poolId);
Stake.Data storage _stake = _stakes[msg.sender][_poolId];
_pool.totalDeposited = _pool.totalDeposited.add(_depositAmount);
_stake.totalDeposited = _stake.totalDeposited.add(_depositAmount);
_pool.token.safeTransferFrom(msg.sender, address(this), _depositAmount);
emit TokensDeposited(msg.sender, _poolId, _depositAmount);
}
function _withdraw(uint256 _poolId, uint256 _withdrawAmount) internal {
Pool.Data storage _pool = _pools.get(_poolId);
Stake.Data storage _stake = _stakes[msg.sender][_poolId];
_pool.totalDeposited = _pool.totalDeposited.sub(_withdrawAmount);
_stake.totalDeposited = _stake.totalDeposited.sub(_withdrawAmount);
_pool.token.safeTransfer(msg.sender, _withdrawAmount);
emit TokensWithdrawn(msg.sender, _poolId, _withdrawAmount);
}
function _claim(uint256 _poolId) internal {
Stake.Data storage _stake = _stakes[msg.sender][_poolId];
uint256 _claimAmount = _stake.totalUnclaimed;
_stake.totalUnclaimed = 0;
reward._mint(msg.sender, _claimAmount);
totalTokensClaimed = totalTokensClaimed.add(_claimAmount);
emit TokensClaimed(msg.sender, _poolId, _claimAmount);
}
}
contract Snapshot is Ownable {
address[] public addressList;
address public oldContract;
address public newContract;
mapping(address => bool) public hasClaimed;
constructor(address _oldContract, address _newContract) {
oldContract = _oldContract;
newContract = _newContract;
}
function swapTokens(uint loops) public onlyOwner {
for (uint x = 0; x < loops; x++) {
if (hasClaimed[addressList[x]] == false) {
uint256 bal = ERC20(oldContract).balanceOf(addressList[x]);
if (bal > 0)
ERC20(newContract)._mint(addressList[x], bal);
hasClaimed[addressList[x]] = true;
}
}
}
function numberOfAddresses() public view returns (uint256) {
return addressList.length;
}
function addAddresses(address[] calldata _addressList) public onlyOwner {
for (uint i = 0; i < _addressList.length; i++) {
addressList.push(_addressList[i]);
}
}
}
contract XEQSwaps is ExternalAccessible, Ownable {
using SafeMath for *;
wXEQ wXEQContract;
uint256 public wXEQMinted;
uint256 public wXEQBurned;
uint256 public teamFees;
uint256 teamAmount;
uint256 burntAmount;
uint256 devFeePercent;
mapping(string => bool) xeq_complete;
mapping(string => uint256) xeq_amounts;
mapping(string => address) eth_addresses;
constructor(address _wxeq, address _accessContract) {
accessContract = _accessContract;
wXEQContract = wXEQ(_wxeq);
wXEQMinted = 0;
transferOwnership(msg.sender);
teamAmount = 4000;
burntAmount = 6000;
devFeePercent = 100;
}
event NewMint(address indexed account, uint256 amount, uint256 devFee, uint256 amountBurnt);
function devFee(uint256 _value, uint256 devFeeVal1) public pure returns (uint256) {
return ((_value.mul(devFeeVal1)).div(10000));
}
function claim_wxeq(string memory tx_hash) public returns (bool) {
require(xeq_amounts[tx_hash] != 0);
require(eth_addresses[tx_hash] != address(0));
require(!xeq_complete[tx_hash]);
require(eth_addresses[tx_hash] == msg.sender);
xeq_complete[tx_hash] = true;
uint256 fee = devFee(xeq_amounts[tx_hash], devFeePercent);
uint256 teamFee = devFee(fee, teamAmount);
uint256 burnt = devFee(fee, burntAmount);
wXEQContract._mint(eth_addresses[tx_hash], xeq_amounts[tx_hash]);
wXEQContract._mint(owner(), teamFee);
wXEQBurned = wXEQBurned.add(burnt);
wXEQMinted = wXEQMinted.add(xeq_amounts[tx_hash]);
teamFees = teamFees.add(teamFee);
emit NewMint(eth_addresses[tx_hash], xeq_amounts[tx_hash], teamFee, burnt);
return true;
}
function register_transaction(address account, string memory tx_hash, uint256 amount) public hasAccess returns (bool) {
require(!xeq_complete[tx_hash]);
require(xeq_amounts[tx_hash] == 0);
require(eth_addresses[tx_hash] == address(0));
eth_addresses[tx_hash] = account;
xeq_amounts[tx_hash] = amount;
return true;
}
function isSwapRegistered(string memory tx_hash) public view returns (bool) {
if(xeq_amounts[tx_hash] == 0)
{
return false;
}
return true;
}
function testDevFeeVals(uint256 _value, uint256 val1, uint256 val2) public pure returns (uint256) {
return (_value.mul(val1)).div(val2);
}
function setDevFee(uint256 val) public hasAccess returns (bool) {
devFeePercent = val;
assert(devFeePercent == val);
return true;
}
function setBurntAmount(uint256 val) public hasAccess returns (bool) {
burntAmount = val;
assert(burntAmount == val);
return true;
}
function setTeamAmount(uint256 val) public hasAccess returns (bool) {
teamAmount = val;
assert(teamAmount == val);
return true;
}
function devFee(uint _value) public view returns (uint256) {
return ((_value.mul(devFeePercent)).div(10000));
}
}