Source Code
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Vault
Compiler Version
v0.8.23+commit.f704f362
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {IBurner} from "./interfaces/IBurner.sol";
import {IGame} from "./interfaces/IGame.sol";
import {IGameFactory} from "./interfaces/IGameFactory.sol";
import {IMONT} from "./interfaces/IMONT.sol";
import {IMontRewardManager} from "./interfaces/IMontRewardManager.sol";
import {IVault} from "./interfaces/IVault.sol";
/**
* @title Vault Contract
* @notice Manages USDC deposits, withdrawals, and game rewards
* @dev All deposits and withdrawals happen through this contract
*/
contract Vault is IVault, Ownable {
using SafeERC20 for IERC20;
/// @notice Address of ETH, used for events
address public constant ETH = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
/// @notice Address of the MONT token
IMONT public immutable mont;
/// @notice Address of the USDC token
IERC20 public immutable usdc;
/// @notice Address of the Burner contract
IBurner public burner;
/// @notice Address of the GameFactory contract
IGameFactory public gameFactory;
/// @notice Address of the MontRewardManager contract
IMontRewardManager public montRewardManager;
/// @notice Maximum total bet amount in percentage. Default is 200, means 2%
uint256 public maximimBetRate;
/// @notice Minimum bet amount. Default is 1000000, means 1 USDC
uint256 public minimumBetAmount;
/**
* @notice Constructor to set initial values
* @param _mont Address of the Dumont token contract
* @param _usdc Address of the USDC token contract
* @param _burner Address of the burner contract used to sell USDC and burn MONT tokens
* @param _gameFactory Address of the GameFactory contract
* @param _montRewardManager Address of the RewardManager contract
* @param _minimumBetAmount Minimum amount of USDC that a player can place as a bet
*/
constructor(
IMONT _mont,
IERC20 _usdc,
IBurner _burner,
IGameFactory _gameFactory,
IMontRewardManager _montRewardManager,
uint256 _minimumBetAmount
) Ownable(msg.sender) {
mont = _mont;
usdc = _usdc;
burner = _burner;
maximimBetRate = 200;
gameFactory = _gameFactory;
minimumBetAmount = _minimumBetAmount;
montRewardManager = _montRewardManager;
}
/**
* @notice Changes the address of the Burner contract
* @param _burner The new address of the Burner contract
* @dev Emits BurnerChanged event
*/
function setBurner(IBurner _burner) external onlyOwner {
emit BurnerChanged(address(burner), address(_burner));
burner = _burner;
}
/**
* @notice Changes the address of the GameFactory contract
* @param _gameFactory The new address of the GameFactory contract
* @dev Emits GameFactoryChanged event
*/
function setGameFactory(IGameFactory _gameFactory) external onlyOwner {
emit GameFactoryChanged(address(gameFactory), address(_gameFactory));
if (address(gameFactory) != address(0)) {
revert GameFactoryAlreadySet();
}
gameFactory = _gameFactory;
}
/**
* @notice Changes the address of the MontRewardManager contract
* @param _montRewardManager The address of the new MontRewardManager contract
* @dev Emits RewardManagerChanged event
*/
function setMontRewardManager(IMontRewardManager _montRewardManager) external onlyOwner {
emit RewardManagerChanged(address(montRewardManager), address(_montRewardManager));
montRewardManager = _montRewardManager;
}
/**
* @notice Allows admins to deposit USDC into the contract
* @param _amount The amount of USDC to deposit
* @dev Emits Deposited event
*/
function deposit(uint256 _amount) external onlyOwner {
usdc.safeTransferFrom(msg.sender, address(this), _amount);
emit Deposited(_amount);
}
/**
* @notice Allows the owner to withdraw a specified amount of tokens
* @param _token The address of the ERC20 token to withdraw
* @param _amount The amount of tokens to withdraw
* @param _recipient The address to receive the withdrawn tokens
* @dev Emits Withdrawn event
*/
function withdraw(address _token, uint256 _amount, address _recipient) external onlyOwner {
IERC20(_token).safeTransfer(_recipient, _amount);
emit Withdrawn(_token, _amount, _recipient);
}
/**
* @notice Allows the owner to withdraw ETH from the contract
* @param _recipient The address to receive the withdrawn ETH
* @dev Emits Withdrawn event
*/
function withdrawETH(address _recipient) external onlyOwner {
uint256 balance = address(this).balance;
(bool success,) = _recipient.call{value: balance}("");
if (!success) {
revert FailedToSendEther();
}
emit Withdrawn(ETH, balance, _recipient);
}
/**
* @notice Notifies the Vault contract that a player lost a bet and sends USDC if player is the winner
* @param _gameId Id of the game
* @param _betAmount Amount of the bet in USDC
* @param _totalAmount Amount of the bet multiplied by the odds
* @param _houseEdgeAmount The house edge amount reducted from the total amount if the player wins
* @param _isPlayerWinner Whether or not the player won or not
* @dev Emits PlayerRewardsTransferred event
*/
function transferPlayerRewards(
uint256 _gameId,
uint256 _betAmount,
uint256 _totalAmount,
uint256 _houseEdgeAmount,
bool _isPlayerWinner
) external {
IGameFactory.GameDetails memory game = gameFactory.games(_gameId);
if (game.gameAddress != msg.sender) {
revert NotAuthorized(msg.sender);
}
uint256 houseEdge = _betAmount / 10;
if (_isPlayerWinner) {
houseEdge = _houseEdgeAmount;
}
uint256 burnAmount = (houseEdge * 8) / 10;
usdc.safeTransfer(address(burner), burnAmount);
if (_isPlayerWinner) {
usdc.safeTransfer(game.player, _totalAmount);
emit PlayerRewardsTransferred(game.player, _totalAmount);
}
montRewardManager.transferPlayerRewards(_betAmount, _totalAmount, houseEdge, game.player, _isPlayerWinner);
}
/**
* @notice Changes the minimum bet amount of USDC
* @param _minimumBetAmount The new minimum bet amount
* @dev Emits MinimumBetAmountChanged event
*/
function setMinimumBetAmount(uint256 _minimumBetAmount) external onlyOwner {
emit MinimumBetAmountChanged(minimumBetAmount, _minimumBetAmount);
minimumBetAmount = _minimumBetAmount;
}
/**
* @notice Changes the percentage of USDC in the Vault that can be sent as the reward
* @param _maximumBetRate The new maximim bet rate
* @dev Emits MaximumBetRateChanged event
*/
function setMaximumBetRate(uint256 _maximumBetRate) external onlyOwner {
emit MaximumBetRateChanged(maximimBetRate, _maximumBetRate);
maximimBetRate = _maximumBetRate;
}
/**
* @notice Returns the maximum bet amount a player can place
*/
function getMaximumBetAmount() external view returns (uint256) {
uint256 usdcAmount = usdc.balanceOf(address(this));
return (usdcAmount * maximimBetRate) / 10000;
}
/**
* @notice Returns the minimum bet amount a player can place
*/
function getMinimumBetAmount() external view returns (uint256) {
return minimumBetAmount;
}
receive() external payable {}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
constructor(address initialOwner) {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
import {IERC20Permit} from "../extensions/IERC20Permit.sol";
import {Address} from "../../../utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
/**
* @dev An operation with an ERC20 token failed.
*/
error SafeERC20FailedOperation(address token);
/**
* @dev Indicates a failed `decreaseAllowance` request.
*/
error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
forceApprove(token, spender, oldAllowance + value);
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
* value, non-reverting calls are assumed to be successful.
*/
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);
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
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);
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data);
if (returndata.length != 0 && !abi.decode(returndata, (bool))) {
revert SafeERC20FailedOperation(address(token));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0;
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IMONT} from "./IMONT.sol";
import {ISwapRouter02} from "./Uniswap/ISwapRouter02.sol";
/**
* @title Burner contract burns MONT tokens
* @notice Burner is used to swap USDC to MONT and burn MONT
*/
interface IBurner {
/**
* @notice Emitted when MONT tokens are burned
* @param _usdcAmount The amount of USDC swapped
* @param _montAmount The amount of MONT burned
*/
event MONTTokensBurned(uint256 indexed _usdcAmount, uint256 indexed _montAmount);
/**
* @notice Throws when there are not enough USDC tokens to burn
*/
error NotEnoughUSDC();
/**
* @notice Throws when deadline is passed for swap using Uniswap SwapRouter
*/
error DeadlinePassed();
/**
* @notice Returns the MONT token address
*/
function mont() external returns (IMONT);
/**
* @notice Returns the USDC token address
*/
function usdc() external returns (IERC20);
/**
* @notice Returns the Uniswap SwapRouter contract address
*/
function swapRouter() external returns (ISwapRouter02);
/**
* @notice Returns the Uniswap USDC-MONT pool fee tier
*/
function uniswapPoolFee() external returns (uint24);
/**
* @notice Swaps USDC to MONT and burns MONT tokens
* @param _amountOutMinimum The minimum amount of MONT to burn
* @param _deadline Deadline of the swap
*/
function burnTokens(uint256 _amountOutMinimum, uint256 _deadline) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
/**
* @title A single-player game contract where the player guesses card numbers
* @notice The server sets hashed numbers inside the contract, and the player can guess each card
* @dev The contract uses a commit-reveal mechanism to hide the deck of cards initially
*/
interface IGame {
enum CardStatus {
SECRETED,
GUESSED,
CLAIMED,
FREE_REVEAL_REQUESTED,
REVEALED
}
struct Card {
uint256 betAmount;
uint256 totalAmount;
uint256 houseEdgeAmount;
uint256 requestedAt;
uint256 revealedNumber;
uint256 guessedNumbers;
bytes32 hash;
bytes32 revealedSalt;
CardStatus status;
}
/**
* @notice Emitted when revealCard is called for a specific card
* @param _gameId Game id
* @param _index Index of the card
* @param _number Revealed number for the card
* @param _salt Revealed salt for the card
*/
event CardRevealed(uint256 indexed _gameId, uint256 indexed _index, uint256 indexed _number, bytes32 _salt);
/**
* @notice Emitted when guessCard is called for a specific card
* @param _gameId Game id
* @param _index Index of the card
* @param _usdcAmount USDC amount betted for the card by the player
* @param _guessedNumbers Numbers guessed by the player
*/
event CardGuessed(
uint256 indexed _gameId, uint256 indexed _index, uint256 indexed _usdcAmount, uint256 _guessedNumbers
);
/**
* @notice Emitted when requestFreeRevealCard is called
* @param _gameId Game id
* @param _index Index of the card
* @param _timestamp Timestamp
*/
event RevealFreeCardRequested(uint256 indexed _gameId, uint256 indexed _index, uint256 _timestamp);
/**
* @notice Emitted when claimWin is called
* @param _gameId Game id
* @param _index Index of the card
* @param _timestamp Timestamp
*/
event CardClaimed(uint256 indexed _gameId, uint256 indexed _index, uint256 _timestamp);
/**
* @notice Emitted when the game is initialize by a revealer
* @param _gameId Game id
*/
event GameInitialized(uint256 indexed _gameId);
/**
* @notice Thrown when card is not secreted but functions are called
* @param _gameId Game id
* @param _index index Index of the card
*/
error CardIsNotSecret(uint256 _gameId, uint256 _index);
/**
* @notice Thrown when maximum amount of free reveals is requested and more is being requested
* @param _gameId Game id
*/
error MaximumFreeRevealsRequested(uint256 _gameId);
/**
* @notice Thrown when the card is not guessed but function revealCard or else is called
* @param _gameId Game id
* @param _index Index of the card
*/
error CardIsNotGuessed(uint256 _gameId, uint256 _index);
/**
* @notice Thrown when the card status is not FREE_REVEAL_REQUESTED but revealCard is called
* @param _gameId Game id
* @param _index Index of the card
*/
error CardStatusIsNotFreeRevealRequested(uint256 _gameId, uint256 _index);
/**
* @notice Thrown when the bet amount for a card is less than the minumum specified by the vault
* @param _gameId Game id
*/
error BetAmountIsLessThanMinimum(uint256 _gameId);
/**
* @notice Thrown when the bet amount for a card is greater than the maximum specified by the vault
* @param _gameId Game id
* @param _totalAmount Total amount of the bet, meaning betAmount times the rate
*/
error BetAmountIsGreaterThanMaximum(uint256 _gameId, uint256 _totalAmount);
/**
* @notice Thrown when the caller is not authorized
* @param _gameId Game id
* @param _caller Address of the caller
*/
error NotAuthorized(uint256 _gameId, address _caller);
/**
* @notice Thrown when game index is out of bound (0 - 51)
* @param _gameId Game id
* @param _index Index of the card
*/
error InvalidGameIndex(uint256 _gameId, uint256 _index);
/**
* @notice Thrown when no card or all cards are guessed
* @param _gameId Game id
* @param _guessedNumbers The guessed numbers
*/
error InvalidNumbersGuessed(uint256 _gameId, uint256 _guessedNumbers);
/**
* @notice Thrown when claimWin is called before the due time
* @param _gameId Game id
* @param _index Index of the card
*/
error NotYetTimeToClaim(uint256 _gameId, uint256 _index);
/**
* @notice Thrown when the game is expired
* @param _gameId Game id
*/
error GameExpired(uint256 _gameId);
/**
* @notice Thrown when the given salt is invalid
* @param _gameId Game id
* @param _index Index of the card
* @param _number Revealed number
* @param _salt Revealed salt
*/
error InvalidSalt(uint256 _gameId, uint256 _index, uint256 _number, bytes32 _salt);
/**
* @notice Thrown when the remaining selected cards is zero
* @param _gameId Game id
* @param _numbers The selected numbers to get the rate
*/
error DivisionByZeroSelectedCards(uint256 _gameId, uint256 _numbers);
/**
* @notice Thrown when the card is not revealed after CLAIMABLE_AFTER and the operator
* tries to reveal the card
* @param _gameId Game id
* @param _index Index of the card
*/
error CardIsAlreadyClaimable(uint256 _gameId, uint256 _index);
/**
* @notice Thrown when the remaining selected cards is equal to remaining cards
* @param _gameId Game id
* @param _numbers The selected ranks to get the rate
*/
error InvalidSelectedCards(uint256 _gameId, uint256 _numbers);
/**
* @notice Initializes the contract by committing the deck of cards
* @param _hashedDeck The hash of a random deck of cards
*/
function initialize(bytes32[52] calldata _hashedDeck) external;
/**
* @notice Stores the player's guess
* @param _index Index of the card
* @param _betAmount The amount of USDC that the player bets
* @param _guessedNumbers Numbers that the player guessed
*/
function guessCard(uint256 _index, uint256 _betAmount, uint256 _guessedNumbers) external;
/**
* @notice Requests a secret card to be revealed for free
* @param _index Index of the card
*/
function requestFreeRevealCard(uint256 _index) external;
/**
* @notice Claims the player as the winner for a specific card if the revealer does not reveal
* the card after the claimableAfter duration
* @param _index Index of the card
*/
function claimWin(uint256 _index) external;
/**
* @notice Reveals a card and decides the winner and transfers rewards to the player
* @param _index Index of the card
* @param _number The revealed number of the card
* @param _salt The salt that was used to hash the card
*/
function revealCard(uint256 _index, uint256 _number, bytes32 _salt, bool isFreeReveal) external;
/**
* @notice Get cards by their index from 0 to 51
* @param _index Index of the card
*/
function cards(uint256 _index) external returns (Card memory);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {Vault} from "../Vault.sol";
/**
* @title GameFactory Contract
* @notice Facilitates the creation of new games
*/
interface IGameFactory {
struct GameDetails {
address player;
address revealer;
address gameAddress;
uint256 gameDuration;
uint256 claimableAfter;
uint256 maxFreeReveals;
uint256 gameCreationFee;
uint256 gameCreatedAt;
}
/**
* @notice Emitted when the game duration changes
* @param _from The old game duration
* @param _to The new game duration
*/
event GameDurationChanged(uint256 indexed _from, uint256 indexed _to);
/**
* @notice Emitted when the claimable duration changes
* @param _from The old claimable duration
* @param _to The new claimable duration
*/
event ClaimableAfterChanged(uint256 indexed _from, uint256 indexed _to);
/**
* @notice Emitted when the maximum free reveals change
* @param _from The old maximum number
* @param _to The new maximum number
*/
event MaxFreeRevealsChanged(uint256 indexed _from, uint256 indexed _to);
/**
* @notice Emitted when the address of the Vault changes
* @param _from The old Vault address
* @param _to The new Vault address
*/
event VaultChanged(address indexed _from, address indexed _to);
/**
* @notice Emitted when the address of the revealer changes
* @param _from The old revealer address
* @param _to The new revealer address
*/
event RevealerChanged(address indexed _from, address indexed _to);
/**
* @notice Emitted when the game creation fee changes
* @param _from The old game creation fee
* @param _to The new game creation fee
*/
event GameFeeChanged(uint256 indexed _from, uint256 indexed _to);
/**
* @notice Emitted when a new Game is deployed
* @param _gameId Unique ID of the game
* @param _gameAddress Address of the game
* @param _player Address of the player
*/
event GameCreated(uint256 indexed _gameId, address indexed _gameAddress, address indexed _player);
/**
* @notice Emitted when a player sets a referrer during game creation
* @param _referee Address of the referee
* @param _referrer Address of the referrer
*/
event Referred(address indexed _referee, address indexed _referrer);
/**
* @notice Thrown when the caller is not authorized
* @param _caller Address of the caller of the transaction
*/
error NotAuthorized(address _caller);
/**
* @notice Thrown when the referrer address is invalid
* @param _referrer Address of the referrer
* @param _referee Address of the referee
*/
error InvalidReferrer(address _referrer, address _referee);
/**
* @notice Thrown when the referrer address is already set for a referee
* @param _referrer Address of the referrer
* @param _referee Address of the referee
*/
error ReferralAlreadySet(address _referee, address _referrer);
/**
* @notice Thrown when the new game creation fee is higher than MAXIMUM_CREATION_FEE
* @param _newFee The new creation fee amount
* @param _maxFee The maximum creation fee amount
*/
error GameCreationFeeIsTooHigh(uint256 _newFee, uint256 _maxFee);
/**
* @notice Changes the fee required to create a new game
* @param _gameCreationFee The new fee amount in USDC
*/
function setGameCreationFee(uint256 _gameCreationFee) external;
/**
* @notice Changes the duration of future games
* @param _gameDuration The new duration in seconds
*/
function setGameDuration(uint256 _gameDuration) external;
/**
* @notice Changes the claimable duration of future games
* @param _claimableAfter The new duration in seconds
*/
function setClaimableAfter(uint256 _claimableAfter) external;
/**
* @notice Changes the maximum amount of free reveals a player can request for future games
* @param _maxFreeReveals The amount of free reveals a player can request
*/
function setMaxFreeReveals(uint256 _maxFreeReveals) external;
/**
* @notice Changes the manager address for creating new games
* @param _revealer The new manager address
*/
function setRevealer(address _revealer) external;
/**
* @notice Creates a new game using the GameFactory contract and stores related data
* @dev The caller must pay at least the gameCreationFee amount to create a game
* @param _referrer The referrer of the player. Could be the 0x00 address if already set or
* if the player does not want to set one
* @return The ID and the address of the newly created game
*/
function createGame(address _referrer) external returns (uint256, address);
/**
* @notice Retrieves the details of a specific game
* @param _gameId The ID of the game
* @return Details of the specified game
*/
function games(uint256 _gameId) external view returns (GameDetails memory);
/**
* @notice Pauses the GameFactory from creating new games
*/
function pause() external;
/**
* @notice Unpauses the GameFactory from creating new games
*/
function unpause() external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
/**
* @title MONT Token Contract
* @dev Implementation of the Dumont ERC20 token with burn functionality
* @notice This token is used to reward winners of the game
*/
interface IMONT is IERC20 {
/**
* @notice Burns an amount of tokens of the caller
* @param _amount Amount to burn from the caller's balance
* @dev This function can be called by anyone to burn tokens from their own balance
*/
function burn(uint256 _amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
// import {GameFactory} from "../GameFactory.sol";
/**
* @title Reward Manager Interface
* @notice Manages the distribution of MONT rewards to players based on game outcomes
*/
interface IMontRewardManager {
/**
* @notice Emitted when MONT rewards are assigned to a player
* @param _player The address of the player getting the rewards
* @param _reward The amount of MONT rewards assigned
*/
event MontRewardAssigned(address indexed _player, uint256 _reward);
/**
* @notice Emitted when a player claims their MONT tokens
* @param _player The address of the player calling the claim function
* @param _amount The amount of MONT tokens transferred
*/
event MontClaimed(address indexed _player, uint256 _amount);
/**
* @notice Emitted when the TWAP interval changes
* @param _from The old TWAP interval in seconds
* @param _to The new TWAP interval in seconds
*/
event TwapIntervalChanged(uint32 _from, uint32 _to);
/**
* @notice Thrown when a caller is not authorized to perform an operation
*/
error Unauthorized();
/**
* @notice Claims MONT tokens of the caller (player)
* @return amount Amount of MONT tokens transferred to caller
*/
function claim() external returns (uint256 amount);
/**
* @notice Transfers MONT rewards to the player based on game outcome
* @param _betAmount Amount of the bet
* @param _totalAmount Total amount of the bet multiplied by the odds
* @param _houseEdgeAmount The house edge amount reducted from the total amount if the player wins
* @param _player Address of the player
* @param _isPlayerWinner Flag indicating whether the player won the bet
* @return reward Amount of MONT rewards transferred to the player
*/
function transferPlayerRewards(
uint256 _betAmount,
uint256 _totalAmount,
uint256 _houseEdgeAmount,
address _player,
bool _isPlayerWinner
) external returns (uint256 reward);
/**
* @notice Changes the TWAP interval in seconds
* @param _twapInterval The new TWAP interval in seconds
*/
function setTwapInterval(uint32 _twapInterval) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
import {IBurner} from "./IBurner.sol";
import {IGameFactory} from "./IGameFactory.sol";
import {IMontRewardManager} from "./IMontRewardManager.sol";
/**
* @title Vault Contract
* @notice Manages USDC deposits, withdrawals, and game rewards
*/
interface IVault {
/**
* @notice Emitted when the address of the Burner contract changes
* @param _from The old Burner contract address
* @param _to The new Burner contract address
*/
event BurnerChanged(address indexed _from, address indexed _to);
/**
* @notice Emitted when the player received USDC by guessing a card correctly
* @param _player The player address that received the reward
* @param _rewards The amount of USDC rewards that the player received
*/
event PlayerRewardsTransferred(address indexed _player, uint256 _rewards);
/**
* @notice Emitted when the address of the GameFactory contract changes
* @param _from The old GameFactory contract address
* @param _to The new GameFactory contract address
*/
event GameFactoryChanged(address indexed _from, address indexed _to);
/**
* @notice Emitted when the address of the RewardManager contract changes
* @param _from The old RewardManager contract address
* @param _to The new RewardManager contract address
*/
event RewardManagerChanged(address indexed _from, address indexed _to);
/**
* @notice Emitted when a deposit is made into the Vault
* @param _amount The amount deposited
*/
event Deposited(uint256 _amount);
/**
* @notice Emitted when the minimum bet amount is changed
* @param _from The old minimum bet amount
* @param _to The new minimum bet amount
*/
event MinimumBetAmountChanged(uint256 _from, uint256 _to);
/**
* @notice Emitted when a withdrawal is made from the Vault
* @param _token The address of the token being withdrawn
* @param _amount The amount being withdrawn
* @param _recipient The address receiving the withdrawal
*/
event Withdrawn(address indexed _token, uint256 _amount, address indexed _recipient);
/**
* @notice Emitted when the maximum bet rate is changed
* @param _from The old maximum rate
* @param _to The new maximum rate
*/
event MaximumBetRateChanged(uint256 _from, uint256 _to);
/**
* @notice Thrown when the caller is not authorized to perform an action
* @param _caller Caller of the function
*/
error NotAuthorized(address _caller);
/**
* @notice Thrown when an attempt to send ether fails
*/
error FailedToSendEther();
/**
* @notice Thrown when an attempt to change the GameFactory contract address fails
*/
error GameFactoryAlreadySet();
/**
* @notice Changes the address of the Burner contract
* @param _burner The new address of the Burner contract
*/
function setBurner(IBurner _burner) external;
/**
* @notice Changes the address of the MontRewardManager contract
* @param _montRewardManager The address of the new MontRewardManager contract
*/
function setMontRewardManager(IMontRewardManager _montRewardManager) external;
/**
* @notice Allows admins to deposit USDC into the contract
* @param _amount The amount of USDC to deposit
*/
function deposit(uint256 _amount) external;
/**
* @notice Allows the owner to withdraw a specified amount of tokens
* @param _token The address of the ERC20 token to withdraw
* @param _amount The amount of tokens to withdraw
* @param _recipient The address to receive the withdrawn tokens
*/
function withdraw(address _token, uint256 _amount, address _recipient) external;
/**
* @notice Allows the owner to withdraw ETH from the contract
* @param _recipient The address to receive the withdrawn ETH
*/
function withdrawETH(address _recipient) external;
/**
* @notice Notifies the Vault contract that a player lost a bet and sends USDC if player is the winner
* @param _gameId Id of the game
* @param _betAmount Amount of the bet in USDC
* @param _totalAmount Amount of the bet multiplied by the odds
* @param _houseEdgeAmount The house edge amount reducted from the total amount if the player wins
* @param _isPlayerWinner Whether or not the player won or not
*/
function transferPlayerRewards(
uint256 _gameId,
uint256 _betAmount,
uint256 _totalAmount,
uint256 _houseEdgeAmount,
bool _isPlayerWinner
) external;
/**
* @notice Changes the minimum bet amount of USDC
* @param _minimumBetAmount The new minimum bet amount
*/
function setMinimumBetAmount(uint256 _minimumBetAmount) external;
/**
* @notice Returns the maximum bet amount a player can place
*/
function getMaximumBetAmount() external view returns (uint256);
/**
* @notice Returns the minimum bet amount a player can place
*/
function getMinimumBetAmount() external view returns (uint256);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
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;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* ==== Security Considerations
*
* There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
* expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
* considered as an intention to spend the allowance in any specific way. The second is that because permits have
* built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
* take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
* generally recommended is:
*
* ```solidity
* function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
* try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
* doThing(..., value);
* }
*
* function doThing(..., uint256 value) public {
* token.safeTransferFrom(msg.sender, address(this), value);
* ...
* }
* ```
*
* Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
* `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
* {SafeERC20-safeTransferFrom}).
*
* Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
* contracts should have entry points that don't rely on permit.
*/
interface IERC20Permit {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*
* CAUTION: See Security Considerations above.
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)
pragma solidity ^0.8.20;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev The ETH balance of the account is not enough to perform the operation.
*/
error AddressInsufficientBalance(address account);
/**
* @dev There's no code at `target` (it is not a contract).
*/
error AddressEmptyCode(address target);
/**
* @dev A call to an address target failed. The target may have reverted.
*/
error FailedInnerCall();
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
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();
}
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason or custom error, it is bubbled
* up by this function (like regular Solidity function calls). However, if
* the call reverted with no returned reason, this function reverts with a
* {FailedInnerCall} error.
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*/
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);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*/
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);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
* was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
* unsuccessful call.
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata
) internal view returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
// only check if target is a contract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
if (returndata.length == 0 && target.code.length == 0) {
revert AddressEmptyCode(target);
}
return returndata;
}
}
/**
* @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
* revert reason or with a default {FailedInnerCall} error.
*/
function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
if (!success) {
_revert(returndata);
} else {
return returndata;
}
}
/**
* @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
*/
function _revert(bytes memory returndata) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert FailedInnerCall();
}
}
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;
/**
* @title Router token swapping functionality
* @notice Functions for swapping tokens via Uniswap V3
*/
interface ISwapRouter02 {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
/**
* @notice Swaps `amountIn` of one token for as much as possible of another token
* @param params The parameters necessary for the swap, encoded as `ExactInputSingleParams` in calldata
* @return amountOut The amount of the received token
*/
function exactInputSingle(ExactInputSingleParams calldata params) external payable returns (uint256 amountOut);
}{
"remappings": [
"@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/",
"@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
"@prb/math/=node_modules/@prb/math/",
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IMONT","name":"_mont","type":"address"},{"internalType":"contract IERC20","name":"_usdc","type":"address"},{"internalType":"contract IBurner","name":"_burner","type":"address"},{"internalType":"contract IGameFactory","name":"_gameFactory","type":"address"},{"internalType":"contract IMontRewardManager","name":"_montRewardManager","type":"address"},{"internalType":"uint256","name":"_minimumBetAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"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":[],"name":"FailedToSendEther","type":"error"},{"inputs":[],"name":"GameFactoryAlreadySet","type":"error"},{"inputs":[{"internalType":"address","name":"_caller","type":"address"}],"name":"NotAuthorized","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"}],"name":"BurnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Deposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"}],"name":"GameFactoryChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_from","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_to","type":"uint256"}],"name":"MaximumBetRateChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_from","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_to","type":"uint256"}],"name":"MinimumBetAmountChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"},{"indexed":false,"internalType":"uint256","name":"_rewards","type":"uint256"}],"name":"PlayerRewardsTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"}],"name":"RewardManagerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"_recipient","type":"address"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"ETH","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"burner","outputs":[{"internalType":"contract IBurner","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gameFactory","outputs":[{"internalType":"contract IGameFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMaximumBetAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMinimumBetAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximimBetRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumBetAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mont","outputs":[{"internalType":"contract IMONT","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"montRewardManager","outputs":[{"internalType":"contract IMontRewardManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IBurner","name":"_burner","type":"address"}],"name":"setBurner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IGameFactory","name":"_gameFactory","type":"address"}],"name":"setGameFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maximumBetRate","type":"uint256"}],"name":"setMaximumBetRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minimumBetAmount","type":"uint256"}],"name":"setMinimumBetAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IMontRewardManager","name":"_montRewardManager","type":"address"}],"name":"setMontRewardManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gameId","type":"uint256"},{"internalType":"uint256","name":"_betAmount","type":"uint256"},{"internalType":"uint256","name":"_totalAmount","type":"uint256"},{"internalType":"uint256","name":"_houseEdgeAmount","type":"uint256"},{"internalType":"bool","name":"_isPlayerWinner","type":"bool"}],"name":"transferPlayerRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"usdc","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_token","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_recipient","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"}],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60c06040523480156200001157600080fd5b506040516200122f3803806200122f833981016040819052620000349162000129565b33806200005b57604051631e4fbdf760e01b81526000600482015260240160405180910390fd5b6200006681620000c0565b506001600160a01b0395861660805293851660a052600180549386166001600160a01b031994851617905560c8600455600280549286169284169290921790915560059290925560038054929093169116179055620001b1565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b03811681146200012657600080fd5b50565b60008060008060008060c087890312156200014357600080fd5b8651620001508162000110565b6020880151909650620001638162000110565b6040880151909550620001768162000110565b6060880151909450620001898162000110565b60808801519093506200019c8162000110565b8092505060a087015190509295509295509295565b60805160a05161103c620001f3600039600081816101f601528181610516015281816105550152818161071101526109c701526000610334015261103c6000f3fe6080604052600436106101395760003560e01c80638322fff2116100ab578063a0bb97f11161006f578063a0bb97f11461036b578063a996d6ce1461038b578063aebaffb7146103ab578063b6b55f25146103cb578063ea4fcec1146103eb578063f2fde38b1461040b57600080fd5b80638322fff2146102bc57806385bfd47c146102e45780638da5cb5b146103045780639ccf0e22146103225780639e7e78a51461035657600080fd5b80634b56614d116100fd5780634b56614d1461021857806368c6c84f1461023b578063690d83201461025157806369328dec14610271578063715018a61461029157806378e9f1ba146102a657600080fd5b80632563284c1461014557806327810b6e146101675780632be2438b146101a457806331908d2f146101c45780633e413bee146101e457600080fd5b3661014057005b600080fd5b34801561015157600080fd5b50610165610160366004610dbd565b61042b565b005b34801561017357600080fd5b50600154610187906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101b057600080fd5b506101656101bf366004610e0a565b61065d565b3480156101d057600080fd5b506101656101df366004610e0a565b6106a6565b3480156101f057600080fd5b506101877f000000000000000000000000000000000000000000000000000000000000000081565b34801561022457600080fd5b5061022d6106ef565b60405190815260200161019b565b34801561024757600080fd5b5061022d60045481565b34801561025d57600080fd5b5061016561026c366004610e38565b61079f565b34801561027d57600080fd5b5061016561028c366004610e55565b610875565b34801561029d57600080fd5b506101656108d6565b3480156102b257600080fd5b5061022d60055481565b3480156102c857600080fd5b5061018773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b3480156102f057600080fd5b50600254610187906001600160a01b031681565b34801561031057600080fd5b506000546001600160a01b0316610187565b34801561032e57600080fd5b506101877f000000000000000000000000000000000000000000000000000000000000000081565b34801561036257600080fd5b5060055461022d565b34801561037757600080fd5b50600354610187906001600160a01b031681565b34801561039757600080fd5b506101656103a6366004610e38565b6108ea565b3480156103b757600080fd5b506101656103c6366004610e38565b61094e565b3480156103d757600080fd5b506101656103e6366004610e0a565b6109b2565b3480156103f757600080fd5b50610165610406366004610e38565b610a25565b34801561041757600080fd5b50610165610426366004610e38565b610ab3565b600254604051630117a5b960e41b8152600481018790526000916001600160a01b03169063117a5b909060240161010060405180830381865afa158015610476573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049a9190610ea7565b60408101519091506001600160a01b031633146104d157604051634a0bfec160e01b81523360048201526024015b60405180910390fd5b60006104de600a87610f5a565b905082156104e95750825b6000600a6104f8836008610f7c565b6105029190610f5a565b60015490915061053f906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000008116911683610af1565b83156105c457825161057c906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169088610af1565b82600001516001600160a01b03167f9da7880f5bd43aeb9f5ed3d6ba32e2c577d48486f99460dfb8d9066be3786806876040516105bb91815260200190565b60405180910390a25b600354835160405163a4d45e4160e01b8152600481018a905260248101899052604481018590526001600160a01b039182166064820152861515608482015291169063a4d45e419060a4016020604051808303816000875af115801561062e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106529190610fa1565b505050505050505050565b610665610b55565b60055460408051918252602082018390527ffa601290e9b61618da05df1bc352366e1da989093db0c7749084c9aa9650c999910160405180910390a1600555565b6106ae610b55565b60045460408051918252602082018390527f69e4694af003c159ca38b878975e589469f34bc363a1382d5fc76d19b075c4e5910160405180910390a1600455565b6040516370a0823160e01b815230600482015260009081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077c9190610fa1565b90506127106004548261078f9190610f7c565b6107999190610f5a565b91505090565b6107a7610b55565b60405147906000906001600160a01b0384169083908381818185875af1925050503d80600081146107f4576040519150601f19603f3d011682016040523d82523d6000602084013e6107f9565b606091505b505090508061081b57604051630dcf35db60e41b815260040160405180910390fd5b6040518281526001600160a01b0384169073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee907fcbcdbdf10631a43cc99c80acace8232649421c3f4f73919f16013d47c83a687a906020015b60405180910390a3505050565b61087d610b55565b6108916001600160a01b0384168284610af1565b806001600160a01b0316836001600160a01b03167fcbcdbdf10631a43cc99c80acace8232649421c3f4f73919f16013d47c83a687a8460405161086891815260200190565b6108de610b55565b6108e86000610b82565b565b6108f2610b55565b6001546040516001600160a01b038084169216907f11598a6f397a51e2d811eb266c8d0bf7d851f33940b15261fee59be574aa54a890600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b610956610b55565b6003546040516001600160a01b038084169216907f4405f9e0bdc5d9158767f13871b091cc5c4d109e5a6432173c6dcd94817e12b890600090a3600380546001600160a01b0319166001600160a01b0392909216919091179055565b6109ba610b55565b6109ef6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016333084610bd2565b6040518181527f2a89b2e3d580398d6dc2db5e0f336b52602bbaa51afa9bb5cdf59239cf0d2bea9060200160405180910390a150565b610a2d610b55565b6002546040516001600160a01b038084169216907fca6076d88d3f1df91ac683dc9092b40fb222c1a372a850c804e6caffb91db3b390600090a36002546001600160a01b031615610a915760405163ddb314bf60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b610abb610b55565b6001600160a01b038116610ae557604051631e4fbdf760e01b8152600060048201526024016104c8565b610aee81610b82565b50565b6040516001600160a01b03838116602483015260448201839052610b5091859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050610c11565b505050565b6000546001600160a01b031633146108e85760405163118cdaa760e01b81523360048201526024016104c8565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038481166024830152838116604483015260648201839052610c0b9186918216906323b872dd90608401610b1e565b50505050565b6000610c266001600160a01b03841683610c74565b90508051600014158015610c4b575080806020019051810190610c499190610fba565b155b15610b5057604051635274afe760e01b81526001600160a01b03841660048201526024016104c8565b6060610c8283836000610c8b565b90505b92915050565b606081471015610cb05760405163cd78605960e01b81523060048201526024016104c8565b600080856001600160a01b03168486604051610ccc9190610fd7565b60006040518083038185875af1925050503d8060008114610d09576040519150601f19603f3d011682016040523d82523d6000602084013e610d0e565b606091505b5091509150610d1e868383610d2a565b925050505b9392505050565b606082610d3f57610d3a82610d86565b610d23565b8151158015610d5657506001600160a01b0384163b155b15610d7f57604051639996b31560e01b81526001600160a01b03851660048201526024016104c8565b5080610d23565b805115610d965780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b8015158114610aee57600080fd5b600080600080600060a08688031215610dd557600080fd5b853594506020860135935060408601359250606086013591506080860135610dfc81610daf565b809150509295509295909350565b600060208284031215610e1c57600080fd5b5035919050565b6001600160a01b0381168114610aee57600080fd5b600060208284031215610e4a57600080fd5b8135610d2381610e23565b600080600060608486031215610e6a57600080fd5b8335610e7581610e23565b9250602084013591506040840135610e8c81610e23565b809150509250925092565b8051610ea281610e23565b919050565b6000610100808385031215610ebb57600080fd5b6040519081019067ffffffffffffffff82118183101715610eec57634e487b7160e01b600052604160045260246000fd5b81604052610ef984610e97565b8152610f0760208501610e97565b6020820152610f1860408501610e97565b6040820152606084015160608201526080840151608082015260a084015160a082015260c084015160c082015260e084015160e0820152809250505092915050565b600082610f7757634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610c8557634e487b7160e01b600052601160045260246000fd5b600060208284031215610fb357600080fd5b5051919050565b600060208284031215610fcc57600080fd5b8151610d2381610daf565b6000825160005b81811015610ff85760208186018101518583015201610fde565b50600092019182525091905056fea2646970667358221220f87f36edfec0cd68c0bdd46f91e25f7596e1f8bb468d47b3d85d35a178b40db364736f6c63430008170033000000000000000000000000aa49d1028d89d56f8f7a8a307d216977847da15e000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda029130000000000000000000000004918512d9eff44b2daff216d87a6e59542a552d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f4240
Deployed Bytecode
0x6080604052600436106101395760003560e01c80638322fff2116100ab578063a0bb97f11161006f578063a0bb97f11461036b578063a996d6ce1461038b578063aebaffb7146103ab578063b6b55f25146103cb578063ea4fcec1146103eb578063f2fde38b1461040b57600080fd5b80638322fff2146102bc57806385bfd47c146102e45780638da5cb5b146103045780639ccf0e22146103225780639e7e78a51461035657600080fd5b80634b56614d116100fd5780634b56614d1461021857806368c6c84f1461023b578063690d83201461025157806369328dec14610271578063715018a61461029157806378e9f1ba146102a657600080fd5b80632563284c1461014557806327810b6e146101675780632be2438b146101a457806331908d2f146101c45780633e413bee146101e457600080fd5b3661014057005b600080fd5b34801561015157600080fd5b50610165610160366004610dbd565b61042b565b005b34801561017357600080fd5b50600154610187906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b3480156101b057600080fd5b506101656101bf366004610e0a565b61065d565b3480156101d057600080fd5b506101656101df366004610e0a565b6106a6565b3480156101f057600080fd5b506101877f000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda0291381565b34801561022457600080fd5b5061022d6106ef565b60405190815260200161019b565b34801561024757600080fd5b5061022d60045481565b34801561025d57600080fd5b5061016561026c366004610e38565b61079f565b34801561027d57600080fd5b5061016561028c366004610e55565b610875565b34801561029d57600080fd5b506101656108d6565b3480156102b257600080fd5b5061022d60055481565b3480156102c857600080fd5b5061018773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee81565b3480156102f057600080fd5b50600254610187906001600160a01b031681565b34801561031057600080fd5b506000546001600160a01b0316610187565b34801561032e57600080fd5b506101877f000000000000000000000000aa49d1028d89d56f8f7a8a307d216977847da15e81565b34801561036257600080fd5b5060055461022d565b34801561037757600080fd5b50600354610187906001600160a01b031681565b34801561039757600080fd5b506101656103a6366004610e38565b6108ea565b3480156103b757600080fd5b506101656103c6366004610e38565b61094e565b3480156103d757600080fd5b506101656103e6366004610e0a565b6109b2565b3480156103f757600080fd5b50610165610406366004610e38565b610a25565b34801561041757600080fd5b50610165610426366004610e38565b610ab3565b600254604051630117a5b960e41b8152600481018790526000916001600160a01b03169063117a5b909060240161010060405180830381865afa158015610476573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061049a9190610ea7565b60408101519091506001600160a01b031633146104d157604051634a0bfec160e01b81523360048201526024015b60405180910390fd5b60006104de600a87610f5a565b905082156104e95750825b6000600a6104f8836008610f7c565b6105029190610f5a565b60015490915061053f906001600160a01b037f000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda029138116911683610af1565b83156105c457825161057c906001600160a01b037f000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913169088610af1565b82600001516001600160a01b03167f9da7880f5bd43aeb9f5ed3d6ba32e2c577d48486f99460dfb8d9066be3786806876040516105bb91815260200190565b60405180910390a25b600354835160405163a4d45e4160e01b8152600481018a905260248101899052604481018590526001600160a01b039182166064820152861515608482015291169063a4d45e419060a4016020604051808303816000875af115801561062e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906106529190610fa1565b505050505050505050565b610665610b55565b60055460408051918252602082018390527ffa601290e9b61618da05df1bc352366e1da989093db0c7749084c9aa9650c999910160405180910390a1600555565b6106ae610b55565b60045460408051918252602082018390527f69e4694af003c159ca38b878975e589469f34bc363a1382d5fc76d19b075c4e5910160405180910390a1600455565b6040516370a0823160e01b815230600482015260009081906001600160a01b037f000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda0291316906370a0823190602401602060405180830381865afa158015610758573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061077c9190610fa1565b90506127106004548261078f9190610f7c565b6107999190610f5a565b91505090565b6107a7610b55565b60405147906000906001600160a01b0384169083908381818185875af1925050503d80600081146107f4576040519150601f19603f3d011682016040523d82523d6000602084013e6107f9565b606091505b505090508061081b57604051630dcf35db60e41b815260040160405180910390fd5b6040518281526001600160a01b0384169073eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee907fcbcdbdf10631a43cc99c80acace8232649421c3f4f73919f16013d47c83a687a906020015b60405180910390a3505050565b61087d610b55565b6108916001600160a01b0384168284610af1565b806001600160a01b0316836001600160a01b03167fcbcdbdf10631a43cc99c80acace8232649421c3f4f73919f16013d47c83a687a8460405161086891815260200190565b6108de610b55565b6108e86000610b82565b565b6108f2610b55565b6001546040516001600160a01b038084169216907f11598a6f397a51e2d811eb266c8d0bf7d851f33940b15261fee59be574aa54a890600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b610956610b55565b6003546040516001600160a01b038084169216907f4405f9e0bdc5d9158767f13871b091cc5c4d109e5a6432173c6dcd94817e12b890600090a3600380546001600160a01b0319166001600160a01b0392909216919091179055565b6109ba610b55565b6109ef6001600160a01b037f000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda0291316333084610bd2565b6040518181527f2a89b2e3d580398d6dc2db5e0f336b52602bbaa51afa9bb5cdf59239cf0d2bea9060200160405180910390a150565b610a2d610b55565b6002546040516001600160a01b038084169216907fca6076d88d3f1df91ac683dc9092b40fb222c1a372a850c804e6caffb91db3b390600090a36002546001600160a01b031615610a915760405163ddb314bf60e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0392909216919091179055565b610abb610b55565b6001600160a01b038116610ae557604051631e4fbdf760e01b8152600060048201526024016104c8565b610aee81610b82565b50565b6040516001600160a01b03838116602483015260448201839052610b5091859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050610c11565b505050565b6000546001600160a01b031633146108e85760405163118cdaa760e01b81523360048201526024016104c8565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6040516001600160a01b038481166024830152838116604483015260648201839052610c0b9186918216906323b872dd90608401610b1e565b50505050565b6000610c266001600160a01b03841683610c74565b90508051600014158015610c4b575080806020019051810190610c499190610fba565b155b15610b5057604051635274afe760e01b81526001600160a01b03841660048201526024016104c8565b6060610c8283836000610c8b565b90505b92915050565b606081471015610cb05760405163cd78605960e01b81523060048201526024016104c8565b600080856001600160a01b03168486604051610ccc9190610fd7565b60006040518083038185875af1925050503d8060008114610d09576040519150601f19603f3d011682016040523d82523d6000602084013e610d0e565b606091505b5091509150610d1e868383610d2a565b925050505b9392505050565b606082610d3f57610d3a82610d86565b610d23565b8151158015610d5657506001600160a01b0384163b155b15610d7f57604051639996b31560e01b81526001600160a01b03851660048201526024016104c8565b5080610d23565b805115610d965780518082602001fd5b604051630a12f52160e11b815260040160405180910390fd5b8015158114610aee57600080fd5b600080600080600060a08688031215610dd557600080fd5b853594506020860135935060408601359250606086013591506080860135610dfc81610daf565b809150509295509295909350565b600060208284031215610e1c57600080fd5b5035919050565b6001600160a01b0381168114610aee57600080fd5b600060208284031215610e4a57600080fd5b8135610d2381610e23565b600080600060608486031215610e6a57600080fd5b8335610e7581610e23565b9250602084013591506040840135610e8c81610e23565b809150509250925092565b8051610ea281610e23565b919050565b6000610100808385031215610ebb57600080fd5b6040519081019067ffffffffffffffff82118183101715610eec57634e487b7160e01b600052604160045260246000fd5b81604052610ef984610e97565b8152610f0760208501610e97565b6020820152610f1860408501610e97565b6040820152606084015160608201526080840151608082015260a084015160a082015260c084015160c082015260e084015160e0820152809250505092915050565b600082610f7757634e487b7160e01b600052601260045260246000fd5b500490565b8082028115828204841417610c8557634e487b7160e01b600052601160045260246000fd5b600060208284031215610fb357600080fd5b5051919050565b600060208284031215610fcc57600080fd5b8151610d2381610daf565b6000825160005b81811015610ff85760208186018101518583015201610fde565b50600092019182525091905056fea2646970667358221220f87f36edfec0cd68c0bdd46f91e25f7596e1f8bb468d47b3d85d35a178b40db364736f6c63430008170033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000aa49d1028d89d56f8f7a8a307d216977847da15e000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda029130000000000000000000000004918512d9eff44b2daff216d87a6e59542a552d10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f4240
-----Decoded View---------------
Arg [0] : _mont (address): 0xaA49D1028d89d56f8f7A8A307d216977847da15e
Arg [1] : _usdc (address): 0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Arg [2] : _burner (address): 0x4918512d9EfF44B2daFF216d87A6e59542a552d1
Arg [3] : _gameFactory (address): 0x0000000000000000000000000000000000000000
Arg [4] : _montRewardManager (address): 0x0000000000000000000000000000000000000000
Arg [5] : _minimumBetAmount (uint256): 1000000
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 000000000000000000000000aa49d1028d89d56f8f7a8a307d216977847da15e
Arg [1] : 000000000000000000000000833589fcd6edb6e08f4c7c32d4f71b54bda02913
Arg [2] : 0000000000000000000000004918512d9eff44b2daff216d87a6e59542a552d1
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 00000000000000000000000000000000000000000000000000000000000f4240
Loading...
Loading
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|---|---|---|---|---|
| BASE | 100.00% | $1 | 1,439.5328 | $1,439.53 |
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.