编译器
0.8.17+commit.8df45f5f
文件 1 的 19:AccessControl.sol
pragma solidity ^0.8.0;
import "./IAccessControl.sol";
import "../utils/Context.sol";
import "../utils/Strings.sol";
import "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(uint160(account), 20),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address account) public virtual override {
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 {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
文件 2 的 19:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 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
) internal 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 的 19:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 4 的 19:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 5 的 19:IAccessControl.sol
pragma solidity ^0.8.0;
interface IAccessControl {
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) external view returns (bool);
function getRoleAdmin(bytes32 role) external view returns (bytes32);
function grantRole(bytes32 role, address account) external;
function revokeRole(bytes32 role, address account) external;
function renounceRole(bytes32 role, address account) external;
}
文件 6 的 19:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 7 的 19:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, 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 from,
address to,
uint256 amount
) external returns (bool);
}
文件 8 的 19:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 9 的 19:IFeeCollector.sol
pragma solidity 0.8.17;
interface IFeeCollector {
function calcFee(uint256 _amount) external view returns (uint256);
function onIncreaseFee(address _token) external;
function onVolumeIncrease(uint256 amount) external;
}
文件 10 的 19:IPriceFeed.sol
pragma solidity 0.8.17;
interface IPriceFeed {
function getPrice(address token) external view returns (uint256);
}
文件 11 的 19:IReferralStorage.sol
pragma solidity 0.8.17;
interface IReferralStorage {
function setReward(address _player, address _token, uint256 _amount) external returns (uint256 _reward);
function removeReward(address _player, address _token, uint256 _amount) external;
}
文件 12 的 19:ITokenManager.sol
pragma solidity 0.8.17;
interface ITokenManager {
function mintVestedWINR(address _input, uint256 _amount, address _recipient) external returns (uint256 mintedAmount_);
function takeVestedWINR(address _from, uint256 _amount) external;
function burnVestedWINR(uint256 _amount) external;
function increaseVolume(address _input, uint256 _amount) external;
function decreaseVolume(address _input, uint256 _amount) external;
}
文件 13 的 19:IVault.sol
pragma solidity 0.8.17;
interface IVault {
function getReserve() external view returns (uint256);
function getWlpValue() external view returns (uint256);
function getMinPrice(address _token) external view returns (uint256);
function payout(
address _wagerAsset,
address _escrowAddress,
uint256 _escrowAmount,
address _recipient,
uint256 _totalAmount
) external;
function payin(address _inputToken, address _escrowAddress, uint256 _escrowAmount) external;
function deposit(address _token, address _receiver) external returns (uint256);
function withdraw(address _token, address _receiver) external;
}
文件 14 的 19:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 15 的 19:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../extensions/draft-IERC20Permit.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
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) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
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");
}
}
}
文件 16 的 19:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
文件 17 的 19:VaultManager.sol
pragma solidity 0.8.17;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "./VaultManagerSettings.sol";
contract VaultManager is VaultManagerSettings {
using SafeERC20 for IERC20;
event Escrow(address sender, address token, uint256 amount);
event Payback(address recipient, address token, uint256 amount);
event Withdraw(address token, uint256 amount);
event Refunded(address game, address player, address token, uint256 amount);
uint32 public constant BASIS_POINTS = 1e4;
mapping(address => uint256) public totalEscrowTokens;
function _increaseEscrow(address _token, uint256 _amount) internal {
totalEscrowTokens[_token] += _amount;
}
function _decreaseEscrow(address _token, uint256 _amount) internal {
totalEscrowTokens[_token] -= _amount;
}
function escrow(
address _token,
address _sender,
uint256 _amount
) public onlyGame onlyWhitelistedToken(_token) {
_increaseEscrow(_token, _amount);
tokenManager.increaseVolume(_token, _amount);
transferIn(_token, _sender, _amount);
emit Escrow(_sender, _token, _amount);
}
function setReferralReward(
address _token,
address _player,
uint256 _amount,
uint64 _houseEdge
) public onlyGame onlyWhitelistedToken(_token) returns (uint256 referralReward_) {
if (_amount > 0) {
return referralStorage.setReward(_player, _token, ((_amount * _houseEdge) / BASIS_POINTS));
}
return 0;
}
function removeReferralReward(
address _token,
address _player,
uint256 _amount,
uint64 _houseEdge
) public onlyGame onlyWhitelistedToken(_token) {
referralStorage.removeReward(_player, _token, ((_amount * _houseEdge) / BASIS_POINTS));
}
function refund(
address _token,
uint256 _amount,
uint256 _vWINRAmount,
address _player
) public onlyGame {
_decreaseEscrow(_token, _amount);
tokenManager.decreaseVolume(_token, _amount);
transferOut(_token, _player, _amount);
if (_vWINRAmount != 0) {
tokenManager.takeVestedWINR(_player, _vWINRAmount);
tokenManager.burnVestedWINR(_vWINRAmount);
}
emit Refunded(_msgSender(), _player, _token, _amount);
}
function payback(address _token, address _recipient, uint256 _amount) public onlyGame {
_decreaseEscrow(_token, _amount);
transferOut(_token, _recipient, _amount);
emit Payback(_recipient, _token, _amount);
}
function getEscrowedTokens(
address _token,
uint256 _amount
) public onlyVault onlyWhitelistedToken(_token) {
_decreaseEscrow(_token, _amount);
IERC20(_token).safeTransfer(address(vault), _amount);
emit Withdraw(_token, _amount);
}
function payout(
address _token,
address _recipient,
uint256 _escrowAmount,
uint256 _totalAmount
) public onlyGame {
vault.payout(_token, address(this), _escrowAmount, _recipient, _totalAmount);
}
function payin(
address _token,
uint256 _escrowAmount
) public onlyGame onlyWhitelistedToken(_token) {
vault.payin(_token, address(this), _escrowAmount);
}
function transferIn(
address _token,
address _sender,
uint256 _amount
) public onlyGame onlyWhitelistedToken(_token) {
IERC20(_token).safeTransferFrom(_sender, address(this), _amount);
}
function transferOut(
address _token,
address _recipient,
uint256 _amount
) public onlyGame onlyWhitelistedToken(_token) {
IERC20(_token).safeTransfer(_recipient, _amount);
}
function mintVestedWINR(
address _input,
uint256 _amount,
address _recipient
) public onlyGame returns (uint256 mintedAmount_) {
mintedAmount_ = tokenManager.mintVestedWINR(_input, _amount, _recipient);
}
function getPrice(address _token) public view returns (uint256 price_) {
price_ = vault.getMinPrice(_token);
}
function getEscrowedValue() public view returns (uint256 pendingWagerValue_) {
address[] memory tokenList_ = whitelistedTokenList;
for (uint256 i = 0; i < tokenList_.length; i++) {
pendingWagerValue_ +=
(IERC20(tokenList_[i]).balanceOf(address(this)) * getPrice(tokenList_[i])) /
(10 ** IERC20Metadata(tokenList_[i]).decimals());
}
}
function getMaxWager() external view returns (uint256 maxWager_) {
maxWager_ = (vault.getReserve() * maxWagerPercent) / PRECISION;
uint256 pending_ = getEscrowedValue();
if (maxWager_ > pending_) {
maxWager_ -= pending_;
} else {
maxWager_ = 0;
}
}
function getMinWager(address _game) external view returns (uint256) {
return minWagers[_game];
}
function setMinWagers(
address[] calldata _games,
uint256[] calldata _minWagers
) external onlyGovernance {
require(_games.length == _minWagers.length, "Lengths must be equal");
for (uint256 i = 0; i < _games.length; i++) {
minWagers[_games[i]] = _minWagers[i];
}
}
}
文件 18 的 19:VaultManagerSettings.sol
pragma solidity 0.8.17;
import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/Pausable.sol";
import "../../interfaces/vault/IFeeCollector.sol";
import "../../interfaces/vault/IPriceFeed.sol";
import "../../interfaces/vault/ITokenManager.sol";
import "../../interfaces/vault/IReferralStorage.sol";
import "../../interfaces/vault/IVault.sol";
contract VaultManagerSettings is Pausable, AccessControl {
event TokensUpdated(address[] tokens);
event GameAdded(address game);
event GameRemoved(address game);
event MaxWagerPercentChanged(uint256 percent);
modifier onlyWhitelistedToken(address _token) {
require(whitelistedTokens[_token], "VM: unknown token");
_;
}
modifier onlyGovernance() {
require(hasRole(DEFAULT_ADMIN_ROLE, _msgSender()), "VM: Not governance");
_;
}
modifier onlyGame() {
require(hasRole(GAME_ROLE, _msgSender()), "VM: Not game");
_;
}
modifier onlyVault() {
require(hasRole(VAULT_ROLE, _msgSender()), "VM: Not vault");
_;
}
IERC20 public wlp;
IVault public vault;
IPriceFeed public priceFeed;
IFeeCollector public feeCollector;
ITokenManager public tokenManager;
address[] public whitelistedTokenList;
IReferralStorage public referralStorage;
uint256 public maxWagerPercent = 1e15;
uint256 public constant PRECISION = 1e18;
mapping(address => bool) public whitelistedGames;
mapping(address => bool) public whitelistedTokens;
mapping(address => uint256) public minWagers;
bytes32 public constant GAME_ROLE = bytes32(keccak256("GAME"));
bytes32 public constant VAULT_ROLE = bytes32(keccak256("VAULT"));
constructor() {
_grantRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
function setWlp(IERC20 _wlp) external onlyGovernance {
wlp = _wlp;
}
function setVault(IVault _vault) external onlyGovernance {
if (address(vault) != address(0)) {
revokeRole(VAULT_ROLE, address(vault));
}
vault = _vault;
grantRole(VAULT_ROLE, address(_vault));
}
function setReferralStorage(IReferralStorage _referralStorage) external onlyGovernance {
referralStorage = _referralStorage;
}
function setPriceFeed(IPriceFeed _priceFeed) external onlyGovernance {
priceFeed = _priceFeed;
}
function setFeeCollector(IFeeCollector _feeCollector) external onlyGovernance {
feeCollector = _feeCollector;
}
function setTokenManager(ITokenManager _tokenManager) external onlyGovernance {
tokenManager = _tokenManager;
}
function setMaxWagerPercent(uint256 _maxWagerPercent) external onlyGovernance {
maxWagerPercent = _maxWagerPercent;
emit MaxWagerPercentChanged(_maxWagerPercent);
}
function setWhitelistedTokens(address[] memory _nextTokens) external onlyGovernance {
address[] memory currentList_ = whitelistedTokenList;
delete whitelistedTokenList;
for(uint256 i = 0; i < currentList_.length; i++) {
delete whitelistedTokens[currentList_[i]];
}
whitelistedTokenList = _nextTokens;
for(uint256 i = 0; i < _nextTokens.length; i++) {
whitelistedTokens[whitelistedTokenList[i]] = true;
}
emit TokensUpdated(whitelistedTokenList);
}
function getWhitelistedTokens() public view returns (address[] memory whitelistedTokenList_) {
whitelistedTokenList_ = whitelistedTokenList;
}
function setWhitelistedGame(address _game) external onlyGovernance {
grantRole(GAME_ROLE, _game);
whitelistedGames[_game] = true;
emit GameAdded(_game);
}
function unsetWhitelistedGame(address _game) external onlyGovernance {
revokeRole(GAME_ROLE, _game);
delete whitelistedGames[_game];
emit GameRemoved(_game);
}
function pause() external onlyGovernance {
_pause();
}
function unpause() external onlyGovernance {
_unpause();
}
}
文件 19 的 19:draft-IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
{
"compilationTarget": {
"contracts/games/core/VaultManager.sol": "VaultManager"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Escrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"game","type":"address"}],"name":"GameAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"game","type":"address"}],"name":"GameRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"percent","type":"uint256"}],"name":"MaxWagerPercentChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Payback","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"game","type":"address"},{"indexed":false,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Refunded","type":"event"},{"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":"address[]","name":"tokens","type":"address[]"}],"name":"TokensUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"BASIS_POINTS","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GAME_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VAULT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"escrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeCollector","outputs":[{"internalType":"contract IFeeCollector","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getEscrowedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getEscrowedValue","outputs":[{"internalType":"uint256","name":"pendingWagerValue_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaxWager","outputs":[{"internalType":"uint256","name":"maxWager_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_game","type":"address"}],"name":"getMinWager","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"name":"getPrice","outputs":[{"internalType":"uint256","name":"price_","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":[],"name":"getWhitelistedTokens","outputs":[{"internalType":"address[]","name":"whitelistedTokenList_","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":[],"name":"maxWagerPercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minWagers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_input","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"mintVestedWINR","outputs":[{"internalType":"uint256","name":"mintedAmount_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"payback","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_escrowAmount","type":"uint256"}],"name":"payin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_escrowAmount","type":"uint256"},{"internalType":"uint256","name":"_totalAmount","type":"uint256"}],"name":"payout","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"priceFeed","outputs":[{"internalType":"contract IPriceFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referralStorage","outputs":[{"internalType":"contract IReferralStorage","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_vWINRAmount","type":"uint256"},{"internalType":"address","name":"_player","type":"address"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_player","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint64","name":"_houseEdge","type":"uint64"}],"name":"removeReferralReward","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":"contract IFeeCollector","name":"_feeCollector","type":"address"}],"name":"setFeeCollector","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxWagerPercent","type":"uint256"}],"name":"setMaxWagerPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_games","type":"address[]"},{"internalType":"uint256[]","name":"_minWagers","type":"uint256[]"}],"name":"setMinWagers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IPriceFeed","name":"_priceFeed","type":"address"}],"name":"setPriceFeed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_player","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint64","name":"_houseEdge","type":"uint64"}],"name":"setReferralReward","outputs":[{"internalType":"uint256","name":"referralReward_","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IReferralStorage","name":"_referralStorage","type":"address"}],"name":"setReferralStorage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract ITokenManager","name":"_tokenManager","type":"address"}],"name":"setTokenManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IVault","name":"_vault","type":"address"}],"name":"setVault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_game","type":"address"}],"name":"setWhitelistedGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_nextTokens","type":"address[]"}],"name":"setWhitelistedTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_wlp","type":"address"}],"name":"setWlp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tokenManager","outputs":[{"internalType":"contract ITokenManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalEscrowTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferIn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferOut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_game","type":"address"}],"name":"unsetWhitelistedGame","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract IVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedGames","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"whitelistedTokenList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"whitelistedTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wlp","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"}]