编译器
0.8.24+commit.e11b9ed9
文件 1 的 10:AccessControl.sol
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => 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 returns (bool) {
return _roles[role].hasRole[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 AccessControlUnauthorizedAccount(account, role);
}
}
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
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 returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}
文件 2 的 10:Address.sol
pragma solidity ^0.8.20;
library Address {
error AddressInsufficientBalance(address account);
error AddressEmptyCode(address target);
error FailedInnerCall();
function sendValue(address payable recipient, uint256 amount) internal {
if (address(this).balance < amount) {
revert AddressInsufficientBalance(address(this));
}
(bool success, ) = recipient.call{value: amount}("");
if (!success) {
revert FailedInnerCall();
}
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
if (address(this).balance < value) {
revert AddressInsufficientBalance(address(this));
}
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
function _revert(bytes memory returndata) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}
文件 3 的 10:Context.sol
pragma solidity ^0.8.20;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}
文件 4 的 10:ERC165.sol
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 5 的 10:IAccessControl.sol
pragma solidity ^0.8.20;
interface IAccessControl {
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
error AccessControlBadConfirmation();
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 callerConfirmation) external;
}
文件 6 的 10:IERC165.sol
pragma solidity ^0.8.20;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 7 的 10:IERC20.sol
pragma solidity ^0.8.20;
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 value) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 value) external returns (bool);
function transferFrom(address from, address to, uint256 value) external returns (bool);
}
文件 8 的 10:IERC20Permit.sol
pragma solidity ^0.8.20;
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);
}
文件 9 的 10:SafeERC20.sol
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
error SafeERC20FailedOperation(address token);
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
unchecked {
uint256 currentAllowance = token.allowance(address(this), spender);
if (currentAllowance < requestedDecrease) {
revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
}
forceApprove(token, spender, currentAllowance - requestedDecrease);
}
}
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
_callOptionalReturn(token, approvalCall);
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}
文件 10 的 10:Treasury.sol
pragma solidity ^0.8.24;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IERC20Permit} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol";
import {AccessControl} from "@openzeppelin/contracts/access/AccessControl.sol";
interface IERC20Mint {
function decimals() external view returns (uint256);
}
contract Treasury is AccessControl {
event FeeCollected(uint256 feeEarned, uint256 totalFees);
event Distributed(address to, uint256 amount);
event Refunded(address to, uint256 amount);
event UpkeepChanged(address newUpkeep);
address public approvedToken;
address public upkeep;
uint256 public setupInitiatorFee = 1000;
uint256 public constant FEE_DENOMINATOR = 10000;
uint256 public constant PRECISION_AMPLIFIER = 100000;
bytes32 public constant DISTRIBUTOR_ROLE = keccak256("DISTRIBUTOR_ROLE");
bytes32 public constant ACCOUNTANT_ROLE = keccak256("ACCOUNTANT_ROLE");
uint256 public collectedFee;
uint256 public minDepositAmount = 1;
mapping(address => uint256) public deposits;
mapping(address => uint256) public locked;
constructor(address newApprovedToken) {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
approvedToken = newApprovedToken;
}
function setToken(address token) public onlyRole(DEFAULT_ADMIN_ROLE) {
require(token != address(0), "Zero address");
approvedToken = token;
}
function setSetupFee(uint256 newFee) public onlyRole(DEFAULT_ADMIN_ROLE) {
setupInitiatorFee = newFee;
}
function deposit(uint256 amount) public {
require(amount >= minDepositAmount, "Wrong deposit amount");
uint256 oldBalance = IERC20(approvedToken).balanceOf(address(this));
SafeERC20.safeTransferFrom(
IERC20(approvedToken),
msg.sender,
address(this),
amount * 10 ** IERC20Mint(approvedToken).decimals()
);
uint256 newBalance = IERC20(approvedToken).balanceOf(address(this));
require(
newBalance ==
oldBalance +
amount *
10 ** IERC20Mint(approvedToken).decimals(),
"Token with fee"
);
deposits[msg.sender] +=
amount *
10 ** IERC20Mint(approvedToken).decimals();
}
function depositAndLock(
uint256 amount,
address from
) public onlyRole(DISTRIBUTOR_ROLE) {
require(amount >= minDepositAmount, "Wrong deposit amount");
uint256 oldBalance = IERC20(approvedToken).balanceOf(address(this));
SafeERC20.safeTransferFrom(
IERC20(approvedToken),
from,
address(this),
amount * 10 ** IERC20Mint(approvedToken).decimals()
);
uint256 newBalance = IERC20(approvedToken).balanceOf(address(this));
require(
newBalance ==
oldBalance +
amount *
10 ** IERC20Mint(approvedToken).decimals(),
"Token with fee"
);
locked[from] += amount * 10 ** IERC20Mint(approvedToken).decimals();
}
function depositWithPermit(
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public {
require(amount >= minDepositAmount, "Wrong deposit amount");
uint256 oldBalance = IERC20(approvedToken).balanceOf(address(this));
IERC20Permit(approvedToken).permit(
msg.sender,
address(this),
amount * 10 ** IERC20Mint(approvedToken).decimals(),
deadline,
v,
r,
s
);
SafeERC20.safeTransferFrom(
IERC20(approvedToken),
msg.sender,
address(this),
amount * 10 ** IERC20Mint(approvedToken).decimals()
);
uint256 newBalance = IERC20(approvedToken).balanceOf(address(this));
require(
newBalance ==
oldBalance +
amount *
10 ** IERC20Mint(approvedToken).decimals(),
"Token with fee"
);
deposits[msg.sender] += amount;
}
function depositAndLockWithPermit(
uint256 amount,
address from,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public onlyRole(DISTRIBUTOR_ROLE) {
require(amount >= minDepositAmount, "Wrong deposit amount");
uint256 oldBalance = IERC20(approvedToken).balanceOf(address(this));
IERC20Permit(approvedToken).permit(
from,
address(this),
amount * 10 ** IERC20Mint(approvedToken).decimals(),
deadline,
v,
r,
s
);
SafeERC20.safeTransferFrom(
IERC20(approvedToken),
from,
address(this),
amount * 10 ** IERC20Mint(approvedToken).decimals()
);
uint256 newBalance = IERC20(approvedToken).balanceOf(address(this));
require(
newBalance ==
oldBalance +
amount *
10 ** IERC20Mint(approvedToken).decimals(),
"Token with fee"
);
locked[from] += amount * 10 ** IERC20Mint(approvedToken).decimals();
}
function withdraw(uint256 amount) public {
require(
deposits[msg.sender] >=
amount * 10 ** IERC20Mint(approvedToken).decimals(),
"Wrong amount"
);
deposits[msg.sender] -=
amount *
10 ** IERC20Mint(approvedToken).decimals();
SafeERC20.safeTransfer(
IERC20(approvedToken),
msg.sender,
amount * 10 ** IERC20Mint(approvedToken).decimals()
);
}
function lock(
uint256 amount,
address from
) public onlyRole(DISTRIBUTOR_ROLE) {
require(
deposits[from] >=
amount * 10 ** IERC20Mint(approvedToken).decimals(),
"Insufficent deposit amount"
);
deposits[from] -= amount * 10 ** IERC20Mint(approvedToken).decimals();
locked[from] += amount * 10 ** IERC20Mint(approvedToken).decimals();
}
function refund(
uint256 amount,
address to
) public onlyRole(DISTRIBUTOR_ROLE) {
require(
locked[to] >= amount * 10 ** IERC20Mint(approvedToken).decimals(),
"Wrong amount"
);
locked[to] -= amount * 10 ** IERC20Mint(approvedToken).decimals();
deposits[to] += amount * 10 ** IERC20Mint(approvedToken).decimals();
emit Refunded(to, amount * 10 ** IERC20Mint(approvedToken).decimals());
}
function refundWithFees(
uint256 amount,
address to,
uint256 refundFee
) public onlyRole(DISTRIBUTOR_ROLE) {
amount *= 10 ** IERC20Mint(approvedToken).decimals();
require(locked[to] >= amount, "Wrong amount");
uint256 withdrawnFees = (amount * refundFee) / FEE_DENOMINATOR;
collectedFee += withdrawnFees;
emit FeeCollected(withdrawnFees, collectedFee);
locked[to] -= amount;
deposits[to] += (amount - withdrawnFees);
emit Refunded(to, (amount - withdrawnFees));
}
function withdrawFees(address to, uint256 amount) public {
require(
hasRole(ACCOUNTANT_ROLE, msg.sender) ||
hasRole(DEFAULT_ADMIN_ROLE, msg.sender),
"Invalid role"
);
amount *= 10 ** IERC20Mint(approvedToken).decimals();
require(collectedFee >= amount, "Wrong amount");
collectedFee -= amount;
SafeERC20.safeTransfer(IERC20(approvedToken), to, amount);
}
function distribute(
uint256 amount,
address to,
uint256 gameFee
) public onlyRole(DISTRIBUTOR_ROLE) {
amount *= 10 ** IERC20Mint(approvedToken).decimals();
uint256 withdrawnFees = (amount * gameFee) / FEE_DENOMINATOR;
uint256 wonAmount = amount - withdrawnFees;
collectedFee += withdrawnFees;
emit FeeCollected(withdrawnFees, collectedFee);
deposits[to] += wonAmount;
emit Distributed(to, wonAmount);
}
function distributeBullseye(
uint256 amount,
address to,
uint256 gameFee
) public onlyRole(DISTRIBUTOR_ROLE) {
uint256 withdrawnFees = (amount * gameFee) / FEE_DENOMINATOR;
uint256 wonAmount = amount - withdrawnFees;
collectedFee += withdrawnFees;
emit FeeCollected(withdrawnFees, collectedFee);
deposits[to] += wonAmount;
emit Distributed(to, wonAmount);
}
function distributeWithoutFee(
uint256 rate,
address to,
uint256 usedFee,
uint256 initialDeposit
) public onlyRole(DISTRIBUTOR_ROLE) {
initialDeposit *= 10 ** IERC20Mint(approvedToken).decimals();
uint256 withdrawnFees = (initialDeposit * usedFee) / FEE_DENOMINATOR;
uint256 wonAmount = (initialDeposit - withdrawnFees) +
((initialDeposit - withdrawnFees) * rate) /
(FEE_DENOMINATOR * PRECISION_AMPLIFIER);
deposits[to] += wonAmount;
emit Distributed(to, wonAmount);
}
function calculateSetupRate(
uint256 lostTeamTotal,
uint256 wonTeamTotal,
uint256 setupFee,
address initiator
) external onlyRole(DISTRIBUTOR_ROLE) returns (uint256, uint256) {
lostTeamTotal *= 10 ** IERC20Mint(approvedToken).decimals();
wonTeamTotal *= 10 ** IERC20Mint(approvedToken).decimals();
uint256 withdrawnFees = (lostTeamTotal * setupFee) / FEE_DENOMINATOR;
collectedFee += withdrawnFees;
emit FeeCollected(withdrawnFees, collectedFee);
uint256 lostTeamFee = (lostTeamTotal * setupInitiatorFee) /
FEE_DENOMINATOR;
uint256 wonTeamFee = (wonTeamTotal * setupInitiatorFee) /
FEE_DENOMINATOR;
deposits[initiator] += lostTeamFee + wonTeamFee;
emit Distributed(initiator, lostTeamFee + wonTeamFee);
uint256 rate = ((lostTeamTotal - withdrawnFees - lostTeamFee) *
(FEE_DENOMINATOR * PRECISION_AMPLIFIER)) /
(wonTeamTotal - wonTeamFee);
return (rate, lostTeamFee + wonTeamFee);
}
function calculateUpDownRate(
uint256 lostTeamTotal,
uint256 wonTeamTotal,
uint256 updownFee
) external onlyRole(DISTRIBUTOR_ROLE) returns (uint256 rate) {
lostTeamTotal *= 10 ** IERC20Mint(approvedToken).decimals();
wonTeamTotal *= 10 ** IERC20Mint(approvedToken).decimals();
uint256 lostTeamFee = (lostTeamTotal * updownFee) / FEE_DENOMINATOR;
uint256 wonTeamFee = (wonTeamTotal * updownFee) / FEE_DENOMINATOR;
collectedFee += lostTeamFee + wonTeamFee;
emit FeeCollected(lostTeamFee + wonTeamFee, collectedFee);
rate =
((lostTeamTotal - lostTeamFee) *
(FEE_DENOMINATOR * PRECISION_AMPLIFIER)) /
(wonTeamTotal - wonTeamFee);
}
function setUpkeep(address newUpkeep) public onlyRole(DEFAULT_ADMIN_ROLE) {
require(newUpkeep != address(0), "Zero address");
upkeep = newUpkeep;
emit UpkeepChanged(newUpkeep);
}
function changeMinDepositAmount(
uint256 newMinAmount
) public onlyRole(DEFAULT_ADMIN_ROLE) {
minDepositAmount = newMinAmount;
}
}
{
"compilationTarget": {
"contracts/Treasury.sol": "Treasury"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"newApprovedToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"AddressEmptyCode","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Distributed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feeEarned","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalFees","type":"uint256"}],"name":"FeeCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","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":"newUpkeep","type":"address"}],"name":"UpkeepChanged","type":"event"},{"inputs":[],"name":"ACCOUNTANT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DISTRIBUTOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FEE_DENOMINATOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRECISION_AMPLIFIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"approvedToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"lostTeamTotal","type":"uint256"},{"internalType":"uint256","name":"wonTeamTotal","type":"uint256"},{"internalType":"uint256","name":"setupFee","type":"uint256"},{"internalType":"address","name":"initiator","type":"address"}],"name":"calculateSetupRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"lostTeamTotal","type":"uint256"},{"internalType":"uint256","name":"wonTeamTotal","type":"uint256"},{"internalType":"uint256","name":"updownFee","type":"uint256"}],"name":"calculateUpDownRate","outputs":[{"internalType":"uint256","name":"rate","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMinAmount","type":"uint256"}],"name":"changeMinDepositAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectedFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"from","type":"address"}],"name":"depositAndLock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"from","type":"address"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"depositAndLockWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"depositWithPermit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"deposits","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gameFee","type":"uint256"}],"name":"distribute","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"gameFee","type":"uint256"}],"name":"distributeBullseye","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"rate","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"usedFee","type":"uint256"},{"internalType":"uint256","name":"initialDeposit","type":"uint256"}],"name":"distributeWithoutFee","outputs":[],"stateMutability":"nonpayable","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":"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":"amount","type":"uint256"},{"internalType":"address","name":"from","type":"address"}],"name":"lock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"locked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minDepositAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"refund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"refundFee","type":"uint256"}],"name":"refundWithFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","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":"newFee","type":"uint256"}],"name":"setSetupFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"setToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newUpkeep","type":"address"}],"name":"setUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setupInitiatorFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"upkeep","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdrawFees","outputs":[],"stateMutability":"nonpayable","type":"function"}]