编译器
0.6.12+commit.27d51765
文件 1 的 14:AccessControl.sol
pragma solidity >=0.6.0 <0.8.0;
import "../utils/EnumerableSet.sol";
import "../utils/Address.sol";
import "../utils/Context.sol";
abstract contract AccessControl is Context {
using EnumerableSet for EnumerableSet.AddressSet;
using Address for address;
struct RoleData {
EnumerableSet.AddressSet members;
bytes32 adminRole;
}
mapping (bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
function hasRole(bytes32 role, address account) public view returns (bool) {
return _roles[role].members.contains(account);
}
function getRoleMemberCount(bytes32 role) public view returns (uint256) {
return _roles[role].members.length();
}
function getRoleMember(bytes32 role, uint256 index) public view returns (address) {
return _roles[role].members.at(index);
}
function getRoleAdmin(bytes32 role) public view returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to grant");
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual {
require(hasRole(_roles[role].adminRole, _msgSender()), "AccessControl: sender must be an admin to revoke");
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
emit RoleAdminChanged(role, _roles[role].adminRole, adminRole);
_roles[role].adminRole = adminRole;
}
function _grantRole(bytes32 role, address account) private {
if (_roles[role].members.add(account)) {
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) private {
if (_roles[role].members.remove(account)) {
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 14:Address.sol
pragma solidity >=0.6.2 <0.8.0;
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);
}
}
}
}
文件 3 的 14:Context.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this;
return msg.data;
}
}
文件 4 的 14:ECDSA.sol
pragma solidity >=0.6.0 <0.8.0;
library ECDSA {
function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
if (signature.length != 65) {
revert("ECDSA: invalid signature length");
}
bytes32 r;
bytes32 s;
uint8 v;
assembly {
r := mload(add(signature, 0x20))
s := mload(add(signature, 0x40))
v := byte(0, mload(add(signature, 0x60)))
}
return recover(hash, v, r, s);
}
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
require(uint256(s) <= 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0, "ECDSA: invalid signature 's' value");
require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");
address signer = ecrecover(hash, v, r, s);
require(signer != address(0), "ECDSA: invalid signature");
return signer;
}
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
}
文件 5 的 14:ERC20.sol
pragma solidity >=0.6.0 <0.8.0;
import "../../utils/Context.sol";
import "./IERC20.sol";
import "../../math/SafeMath.sol";
contract ERC20 is Context, IERC20 {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
constructor (string memory name_, string memory symbol_) public {
_name = name_;
_symbol = symbol_;
_decimals = 18;
}
function name() public view virtual returns (string memory) {
return _name;
}
function symbol() public view virtual returns (string memory) {
return _symbol;
}
function decimals() public view virtual returns (uint8) {
return _decimals;
}
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view virtual 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) internal virtual {
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) internal virtual {
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 virtual {
_decimals = decimals_;
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}
文件 6 的 14:EnumerableSet.sol
pragma solidity >=0.6.0 <0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping (bytes32 => uint256) _indexes;
}
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove(Set storage set, bytes32 value) private returns (bool) {
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
bytes32 lastvalue = set._values[lastIndex];
set._values[toDeleteIndex] = lastvalue;
set._indexes[lastvalue] = toDeleteIndex + 1;
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
struct Bytes32Set {
Set _inner;
}
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
struct AddressSet {
Set _inner;
}
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
struct UintSet {
Set _inner;
}
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}
文件 7 的 14:IERC20.sol
pragma solidity >=0.6.0 <0.8.0;
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);
}
文件 8 的 14:ReentrancyGuard.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () internal {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 9 的 14:SafeERC20.sol
pragma solidity >=0.6.0 <0.8.0;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
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, "SafeERC20: decreased allowance below zero");
_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");
}
}
}
文件 10 的 14:SafeMath.sol
pragma solidity >=0.6.0 <0.8.0;
library SafeMath {
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b > a) return (false, 0);
return (true, a - b);
}
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a / b);
}
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
if (b == 0) return (false, 0);
return (true, a % b);
}
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) {
require(b <= a, "SafeMath: subtraction overflow");
return a - b;
}
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) {
require(b > 0, "SafeMath: division by zero");
return a / b;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b > 0, "SafeMath: modulo by zero");
return a % b;
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
return a - b;
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a / b;
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
return a % b;
}
}
文件 11 的 14:WalletTokensalePrivate.sol
pragma solidity ^0.6.12;
import "openzeppelin-solidity/contracts/access/AccessControl.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/utils/ReentrancyGuard.sol";
import "openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import {vcUSDPool} from "contracts/Pool/vcUSDPool.sol";
contract WalletTokensalePrivate is AccessControl, ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for ERC20;
uint256 public totalAmount;
uint256 public totalSold;
uint256 public minAmountToBuy;
uint256 public maxAmountToBuy;
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant SERVICE_ROLE = keccak256("SERVICE_ROLE");
address public govTokenAddress;
address public USDTAddress;
uint256 public factor = 10**12;
uint256 public USDTReceived;
uint256 public USDTClaimed;
uint256 public rate;
uint256 public ratesPrecision = 10**7;
address public vcUSDPoolAddress;
uint256 currentLockNumber = 0;
bool public swapUnlocked = true;
bool public claimUnlocked = false;
struct Lock {
uint256 unlockDate;
uint256 percent;
}
Lock[] public locks;
struct UserInfo {
uint256 amount;
uint256 claimed;
}
mapping(address => UserInfo) public users;
event TokenExchangedFromUsdt(
address indexed spender,
uint256 usdtAmount,
uint256 daovcAmount,
string userId,
uint256 time
);
event TokensClaimed(
address indexed claimer,
uint256 amountClaimed,
uint256 time
);
event TokenExchangedFromFiat(
address indexed spender,
uint256 amount,
uint256 daovcAmount,
uint256 time
);
event RoundStateChanged(bool state, uint256 time);
modifier roundUnlocked() {
require(swapUnlocked, "Round is locked!");
_;
}
modifier claimUnlockedModifier() {
require(claimUnlocked, "Round is locked!");
_;
}
constructor(
address _govTokenAddress,
address _USDTAddress,
uint256 _rate,
uint256 _totalAmount,
uint256 _minAmountToBuy,
uint256 _maxAmountToBuy,
address _vcUSDPoolAddress,
uint256 _usdtReceived,
uint256 _usdtClaimed
) public {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(ADMIN_ROLE, msg.sender);
_setRoleAdmin(ADMIN_ROLE, DEFAULT_ADMIN_ROLE);
govTokenAddress = _govTokenAddress;
USDTAddress = _USDTAddress;
rate = _rate;
totalAmount = _totalAmount;
minAmountToBuy = _minAmountToBuy;
maxAmountToBuy = _maxAmountToBuy;
vcUSDPoolAddress = _vcUSDPoolAddress;
USDTClaimed = _usdtClaimed;
USDTReceived = _usdtReceived;
}
function setRoundState(bool _state) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
swapUnlocked = _state;
emit RoundStateChanged(_state, block.timestamp);
}
function addLock(uint256[] memory _unlockDate, uint256[] memory _percent)
external
{
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
require(
_unlockDate.length == 10,
"unlockDate array must have 10 values!"
);
require(_percent.length == 10, "percent array must have 10 values!");
for (uint256 i = 0; i < _unlockDate.length; i++) {
locks.push(
Lock({percent: _percent[i], unlockDate: _unlockDate[i]})
);
}
}
function swap(uint256 _amountInUsdt, string memory _userId)
external
roundUnlocked
{
UserInfo storage user = users[msg.sender];
uint256 amountInGov = _amountInUsdt.mul(factor).mul(ratesPrecision).div(
rate
);
require(
_amountInUsdt >= minAmountToBuy &&
user.amount.add(amountInGov) <= maxAmountToBuy,
"Amount must must be within the permitted range!"
);
require(
totalSold.add(amountInGov) <= totalAmount,
"All tokens was sold!"
);
ERC20(USDTAddress).safeTransferFrom(
msg.sender,
address(this),
_amountInUsdt
);
USDTReceived = USDTReceived.add(_amountInUsdt);
user.amount = user.amount.add(amountInGov);
totalSold = totalSold.add(amountInGov);
emit TokenExchangedFromUsdt(
msg.sender,
_amountInUsdt,
amountInGov,
_userId,
block.timestamp
);
}
function swapBackend(address _user, uint256 _amountInUsdt)
external
roundUnlocked
{
require(
hasRole(SERVICE_ROLE, msg.sender),
"Caller does not have the service role."
);
UserInfo storage user = users[_user];
uint256 amountInGov = _amountInUsdt.mul(factor).mul(ratesPrecision).div(
rate
);
require(
_amountInUsdt >= minAmountToBuy &&
user.amount.add(amountInGov) <= maxAmountToBuy,
"Amount must must be within the permitted range!"
);
require(
totalSold.add(amountInGov) <= totalAmount,
"All tokens was sold!"
);
USDTReceived = USDTReceived.add(_amountInUsdt);
user.amount = user.amount.add(amountInGov);
totalSold = totalSold.add(amountInGov);
emit TokenExchangedFromFiat(
_user,
_amountInUsdt,
amountInGov,
block.timestamp
);
}
function claim() external nonReentrant claimUnlockedModifier {
UserInfo storage user = users[msg.sender];
require(user.amount > 0, "Nothing to claim");
uint256 newLock = currentLockNumber;
if (newLock <= locks.length - 2) {
while (block.timestamp >= locks[newLock + 1].unlockDate) {
newLock = newLock + 1;
if (newLock == 9) {
break;
}
}
currentLockNumber = newLock;
}
uint256 availableAmount = calcAvailableAmount(msg.sender);
require(availableAmount > 0, "There are not available tokens to claim");
user.claimed = user.claimed.add(availableAmount);
ERC20(govTokenAddress).safeTransfer(msg.sender, availableAmount);
emit TokensClaimed(msg.sender, availableAmount, block.timestamp);
}
function sendUsdtToPool(uint256 _amount) external {
require(
hasRole(SERVICE_ROLE, msg.sender),
"Caller does not have the service role."
);
ERC20(USDTAddress).safeTransfer(vcUSDPoolAddress, _amount);
USDTClaimed = USDTClaimed.add(_amount);
vcUSDPool(vcUSDPoolAddress).sellVcUsdBackend(_amount);
}
function calcAvailableAmount(address _user)
private
view
returns (uint256 availableToken)
{
UserInfo storage user = users[_user];
availableToken = (
user.amount.mul(locks[currentLockNumber].percent).div(100)
);
if (availableToken >= user.claimed) {
availableToken = availableToken.sub(user.claimed);
} else {
availableToken = 0;
}
return availableToken;
}
function getUserInfo(address _user)
external
view
returns (
uint256 amount_,
uint256 available_,
uint256 claimed_,
uint256 currentLockTime_
)
{
UserInfo storage user = users[_user];
uint256 newLock = currentLockNumber;
if (newLock <= locks.length - 2) {
while (block.timestamp >= locks[newLock + 1].unlockDate) {
newLock = newLock + 1;
if (newLock == 9) {
break;
}
}
}
amount_ = user.amount;
claimed_ = user.claimed;
available_ = (user.amount.mul(locks[newLock].percent).div(100));
if (available_ >= user.claimed) {
available_ = available_.sub(user.claimed);
} else {
available_ = 0;
}
if (newLock == locks.length - 1) {
currentLockTime_ = locks[newLock].unlockDate;
} else {
currentLockTime_ = locks[newLock + 1].unlockDate;
}
return (amount_, available_, claimed_, currentLockTime_);
}
function getRoundState() external view returns (bool) {
return swapUnlocked;
}
function removeToken(
address _recepient,
uint256 _amount,
address tokenAddress
) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
require(
_amount <= ERC20(tokenAddress).balanceOf(address(this)),
"Amount must be <= balanceOf(this contract)."
);
ERC20(tokenAddress).safeTransfer(_recepient, _amount);
}
function updateLock(
uint256 _index,
uint256 _percent,
uint256 _unlockDate
) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
locks[_index].percent = _percent;
locks[_index].unlockDate = _unlockDate;
}
function updateUserInfo(
address _user,
uint256 _amount,
uint256 _claimed
) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
UserInfo storage user = users[_user];
user.amount = _amount;
user.claimed = _claimed;
}
function updateTokenAddress(address _govTokenAddress) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
govTokenAddress = _govTokenAddress;
}
function claimUSDT(address _usdtReceiver) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
require(USDTReceived > 0, "Not enough USDT to claim");
ERC20(USDTAddress).safeTransfer(
_usdtReceiver,
USDTReceived.sub(USDTClaimed)
);
USDTClaimed = USDTClaimed.add(USDTReceived.sub(USDTClaimed));
}
function getInfoAboutUsdt()
external
view
returns (uint256 USDTReceived_, uint256 USDTClaimed_)
{
USDTReceived_ = USDTReceived;
USDTClaimed_ = USDTClaimed;
return (USDTReceived_, USDTClaimed_);
}
function getRate() external view returns (uint256) {
return rate;
}
function updateRate(uint256 _rate) public {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
rate = _rate;
}
function updateVcUsdPoolAddress(address _vcUSDPoolAddress) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
vcUSDPoolAddress = _vcUSDPoolAddress;
}
function updateMinimum(uint256 _minAmountToBuy) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
minAmountToBuy = _minAmountToBuy;
}
function updateMaximum(uint256 _maxAmountToBuy) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
maxAmountToBuy = _maxAmountToBuy;
}
function updateCurrentLockNumber(uint256 _newCurrentLock) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
currentLockNumber = _newCurrentLock;
}
function migrateUsers(
address[] memory _users,
uint256[] memory _amounts,
uint256[] memory _claimed
) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
require(
_users.length == _amounts.length,
"Array users and amounts must be the same length!"
);
require(
_users.length == _claimed.length,
"Array users and claimed must be the same length!"
);
for (uint256 i = 0; i < _users.length; i++) {
UserInfo storage user = users[_users[i]];
user.amount = _amounts[i];
user.claimed = _claimed[i];
}
}
function setClaimState(bool _state) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
claimUnlocked = _state;
}
function updateTotalAmount(uint256 _totalAmount) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
totalAmount = _totalAmount;
}
function updateTotalSold(uint256 _totalSold) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
totalSold = _totalSold;
}
function updateFactor(uint256 _factor) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
factor = _factor;
}
function updateUSDTReceived(uint256 _usdtReceived) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
USDTReceived = _usdtReceived;
}
function updateUSDTClaimed(uint256 _usdtClaimed) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
USDTClaimed = _usdtClaimed;
}
}
文件 12 的 14:WalletTokensalePublic.sol
pragma solidity ^0.6.12;
import "openzeppelin-solidity/contracts/access/AccessControl.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/utils/ReentrancyGuard.sol";
import "openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/cryptography/ECDSA.sol";
import {vcUSDPool} from "contracts/Pool/vcUSDPool.sol";
contract WalletTokensalePublic is AccessControl, ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for ERC20;
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant SERVICE_ROLE = keccak256("SERVICE_ROLE");
uint256 public constant AMOUNT_USD = 500000000;
uint256 public totalAmount;
uint256 public totalSold;
uint256 public maxAmountToBuy;
address public govTokenAddress;
address public USDTAddress;
uint256 public factor = 10**12;
uint256 public USDTReceived;
uint256 public USDTClaimed;
uint256 public rate;
uint256 public ratesPrecision = 10**7;
address public vcUSDPoolAddress;
uint256 currentLockNumber = 0;
bool public swapUnlocked = true;
bool public claimUnlocked = false;
struct Lock {
uint256 unlockDate;
uint256 percent;
}
Lock[] public locks;
struct UserInfo {
uint256 amount;
uint256 claimed;
}
mapping(address => UserInfo) public users;
mapping(bytes32 => bool) hashes;
uint256 public swapsCount;
event TokenExchanged(
address indexed spender,
uint256 usdAmount,
uint256 daovcAmount,
uint256 time,
string userId
);
event TokenExchangedFiat(
address indexed spender,
uint256 amount,
uint256 daovcAmount,
uint256 time
);
event TokensClaimed(
address indexed claimer,
uint256 amountClaimed,
uint256 time
);
event RoundStateChanged(bool state, uint256 time);
modifier roundUnlocked() {
require(swapUnlocked, "Round is locked!");
_;
}
modifier claimUnlockedModifier() {
require(claimUnlocked, "Round is locked!");
_;
}
constructor(
address _govTokenAddress,
address _USDTAddress,
uint256 _rate,
uint256 _totalAmount,
uint256 _maxAmountToBuy,
address _vcUSDPoolAddress,
uint256 _usdtReceived,
uint256 _usdtClaimed
) public {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(ADMIN_ROLE, msg.sender);
govTokenAddress = _govTokenAddress;
USDTAddress = _USDTAddress;
rate = _rate;
totalAmount = _totalAmount;
maxAmountToBuy = _maxAmountToBuy;
vcUSDPoolAddress = _vcUSDPoolAddress;
USDTClaimed = _usdtClaimed;
USDTReceived = _usdtReceived;
}
function setRoundState(bool _state) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
swapUnlocked = _state;
emit RoundStateChanged(_state, block.timestamp);
}
function addLock(uint256[] memory _unlockDate, uint256[] memory _percent)
external
{
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
require(
_unlockDate.length == _percent.length,
"unlockDate array and percent arrays must have same values"
);
for (uint256 i = 0; i < _unlockDate.length; i++) {
locks.push(
Lock({percent: _percent[i], unlockDate: _unlockDate[i]})
);
}
}
function swap(
bytes32 hashedMessage,
string memory _userId,
uint256 _sequence,
uint8 _v,
bytes32 _r,
bytes32 _s
) external roundUnlocked {
address service = ECDSA.recover(hashedMessage, _v, _r, _s);
require(hasRole(SERVICE_ROLE, service), "Signed not by a service");
bytes32 message = ECDSA.toEthSignedMessageHash(
keccak256(abi.encodePacked(_userId, _sequence))
);
require(hashedMessage == message, "Incorrect hashed message");
require(
!hashes[message],
"Sequence amount already claimed or dublicated"
);
hashes[message] = true;
swapsCount++;
UserInfo storage user = users[msg.sender];
uint256 amountInGov = AMOUNT_USD.mul(factor).mul(ratesPrecision).div(
rate
);
require(
user.amount.add(amountInGov) <= maxAmountToBuy,
"You cannot swap more tokens"
);
require(
totalSold.add(amountInGov) <= totalAmount,
"All tokens was sold"
);
ERC20(USDTAddress).safeTransferFrom(
msg.sender,
address(this),
AMOUNT_USD
);
USDTReceived = USDTReceived.add(AMOUNT_USD);
user.amount = user.amount.add(amountInGov);
totalSold = totalSold.add(amountInGov);
emit TokenExchanged(
msg.sender,
AMOUNT_USD,
amountInGov,
block.timestamp,
_userId
);
}
function swapBackend(address _user) external roundUnlocked {
require(
hasRole(SERVICE_ROLE, msg.sender),
"Caller does not have the service role"
);
UserInfo storage user = users[_user];
uint256 amountInGov = AMOUNT_USD.mul(factor).mul(ratesPrecision).div(
rate
);
require(
user.amount.add(amountInGov) <= maxAmountToBuy,
"You cannot swap more tokens"
);
require(
totalSold.add(amountInGov) <= totalAmount,
"All tokens was sold"
);
swapsCount++;
USDTReceived = USDTReceived.add(AMOUNT_USD);
user.amount = user.amount.add(amountInGov);
totalSold = totalSold.add(amountInGov);
emit TokenExchangedFiat(_user, AMOUNT_USD, amountInGov, block.timestamp);
}
function claim() external nonReentrant claimUnlockedModifier {
UserInfo storage user = users[msg.sender];
require(user.amount > 0, "Nothing to claim");
uint256 newLock = currentLockNumber;
if (newLock <= locks.length - 2) {
while (block.timestamp >= locks[newLock + 1].unlockDate) {
newLock = newLock + 1;
if (newLock == locks.length - 1) {
break;
}
}
currentLockNumber = newLock;
}
uint256 availableAmount = calcAvailableAmount(msg.sender);
require(availableAmount > 0, "There are not available tokens to claim");
user.claimed = user.claimed.add(availableAmount);
ERC20(govTokenAddress).safeTransfer(msg.sender, availableAmount);
emit TokensClaimed(msg.sender, availableAmount, block.timestamp);
}
function sendUsdtToPool(uint256 _amount) external {
require(
hasRole(SERVICE_ROLE, msg.sender),
"Caller does not have the service role"
);
ERC20(USDTAddress).safeTransfer(vcUSDPoolAddress, _amount);
USDTClaimed = USDTClaimed.add(_amount);
vcUSDPool(vcUSDPoolAddress).sellVcUsdBackend(_amount);
}
function calcAvailableAmount(address _user)
private
view
returns (uint256 availableToken)
{
UserInfo storage user = users[_user];
availableToken = (
user.amount.mul(locks[currentLockNumber].percent).div(100)
);
if (availableToken >= user.claimed) {
availableToken = availableToken.sub(user.claimed);
} else {
availableToken = 0;
}
return availableToken;
}
function getUserInfo(address _user)
external
view
returns (
uint256 amount_,
uint256 available_,
uint256 claimed_,
uint256 currentLockTime_
)
{
UserInfo storage user = users[_user];
uint256 newLock = currentLockNumber;
if (newLock <= locks.length - 2) {
while (block.timestamp >= locks[newLock + 1].unlockDate) {
newLock = newLock + 1;
if (newLock == locks.length - 1) {
break;
}
}
}
amount_ = user.amount;
claimed_ = user.claimed;
available_ = (user.amount.mul(locks[newLock].percent).div(100));
if (available_ >= user.claimed) {
available_ = available_.sub(user.claimed);
} else {
available_ = 0;
}
if (newLock == locks.length - 1) {
currentLockTime_ = locks[newLock].unlockDate;
} else {
currentLockTime_ = locks[newLock + 1].unlockDate;
}
return (amount_, available_, claimed_, currentLockTime_);
}
function getRoundState() external view returns (bool) {
return swapUnlocked;
}
function removeToken(
address _recepient,
uint256 _amount,
address tokenAddress
) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
ERC20(tokenAddress).safeTransfer(_recepient, _amount);
}
function updateLock(
uint256 _index,
uint256 _percent,
uint256 _unlockDate
) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
locks[_index].percent = _percent;
locks[_index].unlockDate = _unlockDate;
}
function updateUserInfo(
address _user,
uint256 _amount,
uint256 _claimed
) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
UserInfo storage user = users[_user];
user.amount = _amount;
user.claimed = _claimed;
}
function updateTokenAddress(address _govTokenAddress) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
govTokenAddress = _govTokenAddress;
}
function claimUSDT(address _usdtReceiver) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
require(USDTReceived > 0, "Not enough USDT to claim");
ERC20(USDTAddress).safeTransfer(
_usdtReceiver,
USDTReceived.sub(USDTClaimed)
);
USDTClaimed = USDTClaimed.add(USDTReceived.sub(USDTClaimed));
}
function getInfoAboutUsdt()
external
view
returns (uint256 USDTReceived_, uint256 USDTClaimed_)
{
USDTReceived_ = USDTReceived;
USDTClaimed_ = USDTClaimed;
return (USDTReceived_, USDTClaimed_);
}
function getRate() external view returns (uint256) {
return rate;
}
function updateRate(uint256 _rate) public {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
rate = _rate;
}
function updateVcUsdPoolAddress(address _vcUSDPoolAddress) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
vcUSDPoolAddress = _vcUSDPoolAddress;
}
function updateMaximum(uint256 _maxAmountToBuy) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
maxAmountToBuy = _maxAmountToBuy;
}
function updateCurrentLockNumber(uint256 _newCurrentLock) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
currentLockNumber = _newCurrentLock;
}
function migrateUsers(
address[] memory _users,
uint256[] memory _amounts,
uint256[] memory _claimed
) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
require(
_users.length == _amounts.length,
"Array users and amounts must be the same length"
);
require(
_users.length == _claimed.length,
"Array users and claimed must be the same length"
);
for (uint256 i = 0; i < _users.length; i++) {
UserInfo storage user = users[_users[i]];
user.amount = _amounts[i];
user.claimed = _claimed[i];
}
}
function setClaimState(bool _state) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
claimUnlocked = _state;
}
function updateTotalAmount(uint256 _totalAmount) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
totalAmount = _totalAmount;
}
function updateTotalSold(uint256 _totalSold) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
totalSold = _totalSold;
}
function updateFactor(uint256 _factor) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
factor = _factor;
}
function updateUSDTReceived(uint256 _usdtReceived) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
USDTReceived = _usdtReceived;
}
function updateUSDTClaimed(uint256 _usdtClaimed) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
USDTClaimed = _usdtClaimed;
}
}
文件 13 的 14:vcUSD.sol
pragma solidity ^0.6.12;
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "openzeppelin-solidity/contracts/access/AccessControl.sol";
contract vcUSDToken is ERC20, AccessControl {
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");
bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) public ERC20(_name, _symbol) {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(ADMIN_ROLE, msg.sender);
_setRoleAdmin(ADMIN_ROLE, DEFAULT_ADMIN_ROLE);
_setupDecimals(_decimals);
}
function mint(address to, uint256 amount) external {
require(hasRole(MINTER_ROLE, msg.sender), "Caller is not an minter");
_mint(to, amount);
}
function burn(address from, uint256 amount) external {
require(hasRole(BURNER_ROLE, msg.sender), "Caller is not an burner");
_burn(from, amount);
}
function _beforeTokenTransfer(
address _from,
address _to,
uint256 _amount
) internal virtual override(ERC20) {
ERC20._beforeTokenTransfer(_from, _to, _amount);
}
}
文件 14 的 14:vcUSDPool.sol
pragma solidity ^0.6.12;
import "openzeppelin-solidity/contracts/access/AccessControl.sol";
import "openzeppelin-solidity/contracts/math/SafeMath.sol";
import "openzeppelin-solidity/contracts/utils/ReentrancyGuard.sol";
import "openzeppelin-solidity/contracts/token/ERC20/SafeERC20.sol";
import "openzeppelin-solidity/contracts/token/ERC20/ERC20.sol";
import "contracts/tokens/vcUSD.sol";
import {WalletTokensalePrivate} from "contracts/Wallets/WalletTokensalePrivate.sol";
contract vcUSDPool is AccessControl, ReentrancyGuard {
using SafeMath for uint256;
using SafeERC20 for ERC20;
bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
bytes32 public constant SERVICE_ROLE = keccak256("SERVICE_ROLE");
bool public saleUnlocked = true;
bool public claimUnlocked = true;
mapping(bytes32 => bool) hashes;
address public vcUSDAddress;
address public USDTAddress;
address public service_backend;
address public privateAddress;
event vcUSDBuy(address indexed user, uint256 amount, uint256 time);
event vcUSDSell(address indexed user, uint256 amount, uint256 time);
event RefferalsClaimed(address indexed user, uint256 amount, uint256 time);
constructor(
address _USDTAddress,
address _vcUSDAddress,
address _service_backend
) public {
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
_setupRole(ADMIN_ROLE, msg.sender);
_setRoleAdmin(ADMIN_ROLE, DEFAULT_ADMIN_ROLE);
_setRoleAdmin(SERVICE_ROLE, ADMIN_ROLE);
vcUSDAddress = _vcUSDAddress;
USDTAddress = _USDTAddress;
service_backend = _service_backend;
_setupRole(SERVICE_ROLE, service_backend);
}
modifier refferalClaimUnlocked() {
require(claimUnlocked, "Claim is locked");
_;
}
modifier salesUnlocked() {
require(saleUnlocked, "Sales is locked!");
_;
}
function airdrop(address[] calldata _addresses, uint256[] calldata _amounts)
external
{
require(hasRole(SERVICE_ROLE, msg.sender), "Caller is not an service");
require(
_addresses.length == _amounts.length,
"Arrays must have the same length"
);
for (uint256 i = 0; i < _addresses.length; i++) {
vcUSDToken(vcUSDAddress).mint(_addresses[i], _amounts[i]);
}
}
function buyVcUSDBackend(uint256 _amount, address _recepient) external {
require(hasRole(SERVICE_ROLE, msg.sender), "Caller is not an service");
require(_amount > 0, "Amount must be above zero!");
vcUSDToken(vcUSDAddress).burn(service_backend, _amount);
ERC20(USDTAddress).safeTransfer(_recepient, _amount);
emit vcUSDBuy(_recepient, _amount, block.timestamp);
}
function sellVcUsdBackend(uint256 _amount) external {
require(hasRole(SERVICE_ROLE, msg.sender), "Caller is not an service");
require(_amount > 0, "Amount must be above zero!");
vcUSDToken(vcUSDAddress).mint(service_backend, _amount);
emit vcUSDSell(service_backend, _amount, block.timestamp);
}
function buyVcUSD(uint256 _amount) external salesUnlocked nonReentrant {
require(_amount > 0, "Amount must be above zero!");
vcUSDToken(vcUSDAddress).burn(msg.sender, _amount);
ERC20(USDTAddress).safeTransfer(msg.sender, _amount);
emit vcUSDBuy(msg.sender, _amount, block.timestamp);
}
function sellVcUsd(uint256 _amount) external salesUnlocked nonReentrant {
require(_amount > 0, "Amount must be above zero!");
ERC20(USDTAddress).safeTransferFrom(msg.sender, address(this), _amount);
vcUSDToken(vcUSDAddress).mint(msg.sender, _amount);
emit vcUSDSell(msg.sender, _amount, block.timestamp);
}
function updateServiceAddress(address _service_backend) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
service_backend = _service_backend;
}
function updateSalesState(bool _state) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
saleUnlocked = _state;
}
function updateVcUSDAddress(address _vcUSDAddress) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
vcUSDAddress = _vcUSDAddress;
}
function claim(
bytes32 hashedMessage,
uint256 _amount,
uint256 _sequence,
uint8 _v,
bytes32 _r,
bytes32 _s,
address _from
) external nonReentrant refferalClaimUnlocked {
address service = recover(hashedMessage, _v, _r, _s);
require(hasRole(SERVICE_ROLE, service), "Signed not by a service");
bytes32 message = keccak256(
abi.encodePacked(msg.sender, _amount, _sequence)
);
message = keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", message)
);
require(hashedMessage == message, "Incorrect hashed message");
require(
!hashes[message],
"Sequence amount already claimed or dublicated."
);
hashes[message] = true;
WalletTokensalePrivate(_from).removeToken(
msg.sender,
_amount,
USDTAddress
);
emit RefferalsClaimed(msg.sender, _amount, block.timestamp);
}
function removeToken(
address _recepient,
uint256 _amount,
address tokenAddress
) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
ERC20(tokenAddress).safeTransfer(_recepient, _amount);
}
function updateClaimState(bool _state) external {
require(hasRole(ADMIN_ROLE, msg.sender), "Caller is not an admin");
claimUnlocked = _state;
}
function recover(
bytes32 hashedMsg,
uint8 v,
bytes32 r,
bytes32 s
) internal pure returns (address) {
require(
uint256(s) <=
0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0,
"ECDSA: invalid signature 's' value"
);
require(v == 27 || v == 28, "ECDSA: invalid signature 'v' value");
address signer = ecrecover(hashedMsg, v, r, s);
require(signer != address(0), "ECDSA: invalid signature");
return signer;
}
}
{
"compilationTarget": {
"contracts/Wallets/WalletTokensalePublic.sol": "WalletTokensalePublic"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_govTokenAddress","type":"address"},{"internalType":"address","name":"_USDTAddress","type":"address"},{"internalType":"uint256","name":"_rate","type":"uint256"},{"internalType":"uint256","name":"_totalAmount","type":"uint256"},{"internalType":"uint256","name":"_maxAmountToBuy","type":"uint256"},{"internalType":"address","name":"_vcUSDPoolAddress","type":"address"},{"internalType":"uint256","name":"_usdtReceived","type":"uint256"},{"internalType":"uint256","name":"_usdtClaimed","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"state","type":"bool"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"RoundStateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"usdAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"daovcAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"},{"indexed":false,"internalType":"string","name":"userId","type":"string"}],"name":"TokenExchanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"daovcAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"TokenExchangedFiat","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountClaimed","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"time","type":"uint256"}],"name":"TokensClaimed","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"AMOUNT_USD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SERVICE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDTAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDTClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"USDTReceived","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_unlockDate","type":"uint256[]"},{"internalType":"uint256[]","name":"_percent","type":"uint256[]"}],"name":"addLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_usdtReceiver","type":"address"}],"name":"claimUSDT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInfoAboutUsdt","outputs":[{"internalType":"uint256","name":"USDTReceived_","type":"uint256"},{"internalType":"uint256","name":"USDTClaimed_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRoundState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getUserInfo","outputs":[{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint256","name":"available_","type":"uint256"},{"internalType":"uint256","name":"claimed_","type":"uint256"},{"internalType":"uint256","name":"currentLockTime_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"govTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"locks","outputs":[{"internalType":"uint256","name":"unlockDate","type":"uint256"},{"internalType":"uint256","name":"percent","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxAmountToBuy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_users","type":"address[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"uint256[]","name":"_claimed","type":"uint256[]"}],"name":"migrateUsers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ratesPrecision","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_recepient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"removeToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"sendUsdtToPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setClaimState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setRoundState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hashedMessage","type":"bytes32"},{"internalType":"string","name":"_userId","type":"string"},{"internalType":"uint256","name":"_sequence","type":"uint256"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"swapBackend","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"swapsCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCurrentLock","type":"uint256"}],"name":"updateCurrentLockNumber","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_factor","type":"uint256"}],"name":"updateFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"},{"internalType":"uint256","name":"_percent","type":"uint256"},{"internalType":"uint256","name":"_unlockDate","type":"uint256"}],"name":"updateLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxAmountToBuy","type":"uint256"}],"name":"updateMaximum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"updateRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_govTokenAddress","type":"address"}],"name":"updateTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_totalAmount","type":"uint256"}],"name":"updateTotalAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_totalSold","type":"uint256"}],"name":"updateTotalSold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_usdtClaimed","type":"uint256"}],"name":"updateUSDTClaimed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_usdtReceived","type":"uint256"}],"name":"updateUSDTReceived","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_claimed","type":"uint256"}],"name":"updateUserInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vcUSDPoolAddress","type":"address"}],"name":"updateVcUsdPoolAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"users","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"claimed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"vcUSDPoolAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]