BaseBase
0xbc...b95d
ETH Wagered

ETH Wagered

ETHw

代币
市值
$1.00
 
价格
2%
此合同的源代码已经过验证!
合同元数据
编译器
0.8.14+commit.80d49f37
语言
Solidity
合同源代码
文件 1 的 10:Cloneable.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

contract Cloneable {

    /**
        @dev Deploys and returns the address of a clone of address(this
        Created by DeFi Mark To Allow Clone Contract To Easily Create Clones Of Itself
        Without redundancy
     */
    function clone() external returns(address) {
        return _clone(address(this));
    }

    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create opcode, which should never revert.
     */
    function _clone(address implementation) internal returns (address instance) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
            instance := create(0, ptr, 0x37)
        }
        require(instance != address(0), "ERC1167: create failed");
    }

}
合同源代码
文件 2 的 10:IERC20.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

interface IERC20 {

    function totalSupply() external view returns (uint256);
    
    function symbol() external view returns(string memory);
    
    function name() external view returns(string memory);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);
    
    /**
     * @dev Returns the number of decimal places
     */
    function decimals() external view returns (uint8);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) 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 `amount` 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 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);

    /**
     * @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);
}
合同源代码
文件 3 的 10:IFeeRecipient.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

interface IFeeRecipient {
    function takeFee(address token, uint256 amount, uint256 partner, address ref) external payable;
}
合同源代码
文件 4 的 10:IGovernanceManager.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

interface IGovernanceManager {
    function RNG() external view returns (address);
    function owner() external view returns (address);
    function chainlinkFeeReceiver() external view returns (address);
    function chainlinkSubscriptionOwner() external view returns (address);
    function referralManager() external view returns (address);
    function projectTokens() external view returns (address);
    function feeReceiver() external view returns (address);
    function claimManager() external view returns (address);
    function house() external view returns (address);
    function isGame(address game) external view returns (bool);
    function userInfoTracker() external view returns (address);
}
合同源代码
文件 5 的 10:IProjectTokensManager.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

interface IProjectTokensManager {
    function isValidPartner(uint256 partnerNonce) external view returns (bool);
    function getFundReceiver(uint256 partner) external view returns (address);
    function isListedToken(address token) external view returns (bool);
    function getWrapper(address token) external view returns (address);
    function getHouse(address token) external view returns (address);
    function getViewer(address token) external view returns (address);
    function isWrappedAsset(address wrapper) external view returns (bool);
    function canPlayForOthers(address addr) external view returns (bool);
    function wrappedAssetManager() external view returns (address);
    function houseManager() external view returns (address);
}
合同源代码
文件 6 的 10:IRNG.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

interface IRNG {
    function requestRandom(uint32 gas, uint32 numResults) external returns (uint256 requestId);
}
合同源代码
文件 7 的 10:ITokenWagerViewer.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

interface ITokenWagerViewer {

    function __init__(address token_) external;

    function wagered(address user, uint256 amount, uint256 GAME_ID, uint256 partnerId) external;

    function getGameData(address user, uint256 GAME_ID) external view returns (uint256 totalWagered, uint256 numGamesPlayed);

    function batchGameData(address user, uint256[] calldata GAME_IDs) external view returns (uint256[] memory totalWagered, uint256[] memory numGamesPlayed);

    function getListOfTotalWageredByProject(uint256[] calldata projects) external view returns (uint256[] memory);

    function getListOfTotalWagered(address[] calldata users) external view returns (uint256[] memory);

    function getListOfTotalWageredPaginated(address[] memory allUsers) external view returns (uint256[] memory);
    
}
合同源代码
文件 8 的 10:IUserInfoTracker.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

interface IUserInfoTracker {
    function wagered(address user, uint256 amount, uint256 GAME_ID, address token, uint256 partnerId) external;
    function createViewer(address token) external returns (address viewer);
    function listAllUsers() external view returns (address[] memory);
    function totalWageredForPartner(uint256 partnerId) external view returns (uint256);
}
合同源代码
文件 9 的 10:PVPOwnable.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

import "./IFeeRecipient.sol";
import "./IGovernanceManager.sol";
import "../ProjectTokens/IProjectTokensManager.sol";
import "../RNGTracker/IRNG.sol";

contract PVPOwnable {

    // Governance Manager
    IGovernanceManager public constant manager = IGovernanceManager(0x22164a57446aD5dE1DBE831784D8029773941678);

    modifier onlyOwner() {
        require(
            msg.sender == manager.owner(),
            'Only Owner'
        );
        _;
    }

    modifier onlyGame() {
        require(
            manager.isGame(msg.sender),
            'UnAuthorized'
        );
        _;
    }

    modifier onlyRNG() {
        require(
            msg.sender == manager.RNG(),
            'Only RNG Contract'
        );
        _;
    }

    modifier onlyValidToken(address token_) {
        require(
            IProjectTokensManager(manager.projectTokens()).isWrappedAsset(token_),
            'Invalid Token'
        );
        _;
    }

    modifier validGameToken(address token_) {
        require(
            token_ == address(0) || IProjectTokensManager(manager.projectTokens()).isWrappedAsset(token_),
            'Invalid Token'
        );
        _;
    }

    modifier validatePlayer(address player) {
        if (player != msg.sender) {
            require(
                IProjectTokensManager(manager.projectTokens()).canPlayForOthers(msg.sender),
                'UnAuthorized To Play For Others'
            );
        }
        _;
    }
}
合同源代码
文件 10 的 10:UserInfo.sol
//SPDX-License-Identifier: MIT
pragma solidity 0.8.14;

import "../GovernanceManager/PVPOwnable.sol";
import "./IUserInfoTracker.sol";
import "./ITokenWagerViewer.sol";
import "../lib/Cloneable.sol";
import "../lib/IERC20.sol";

contract UserInfo is IUserInfoTracker, PVPOwnable {

    // Name + Symbol for wallet support
    string public constant name = "ETH Wagered";
    string public constant symbol = "ETHw";

    // Token Info
    address[] public allTokenViewers;
    mapping ( address => address ) public tokenToViewer;
    address public viewerImplementation;

    // Game Data Structure
    struct GameData {
        uint256 totalWagered;
        uint256 numGamesPlayed;
    }

    // User Info Structure
    struct UserInfoStruct {
        uint256 totalWagered;
        mapping ( uint256 => GameData ) gameData;
        bool exists;
    }

    // Mapping From User To Total WETH Wagered
    mapping ( address => UserInfoStruct ) private userInfo;

    // List Of All Unique Users
    address[] public allUsers;

    // Total Wagers Placed
    uint256 public totalWagersPlaced;

    // Total Wagered
    uint256 public totalWagered;

    // Total Wagered For Partner
    mapping ( uint256 => uint256 ) public override totalWageredForPartner;

    // Old UserInfo to pull data from
    // address private immutable oldUserInfo;

    // Transfer Event
    event Transfer(address indexed from, address indexed to, uint256 value);

    constructor(
        address _viewerImp
        // address oldUserInfo_
    ) {
        viewerImplementation = _viewerImp;
        // oldUserInfo = oldUserInfo_;
    }

    function balanceOf(address user) external view returns (uint256) {
        return userInfo[user].totalWagered;
    }

    function totalSupply() external view returns (uint256) {
        return totalWagered;
    }

    function decimals() external pure returns (uint8) {
        return 18;
    }

    function setViewerImplementation(address implementation) external onlyOwner {
        viewerImplementation = implementation;
    }

    // function initOldUserInfo() external onlyOwner {
    //     require(oldUserInfo != address(0) && allUsers.length == 0, 'Already Init');

    //     address[] memory users = IUserInfoTracker(oldUserInfo).listAllUsers();
    //     uint len = users.length;
    //     for (uint i = 0; i < len;) {
    //         address user_ = users[i];
    //         uint bal = IERC20(oldUserInfo).balanceOf(user_);
    //         userInfo[user_].totalWagered += bal;
    //         allUsers.push(user_);
    //         emit Transfer(address(0), user_, bal);
    //         unchecked { ++i; }
    //     }
    //     totalWagered = IERC20(oldUserInfo).totalSupply();
    //     for (uint i = 0; i < 25;) {
    //         totalWageredForPartner[i] = IUserInfoTracker(oldUserInfo).totalWageredForPartner(i);
    //         unchecked { ++i; }
    //     }
    // }

    function createViewer(address token) external override returns (address viewer) {
        require(
            msg.sender == manager.projectTokens(),
            "Unauthorized"
        );
        return _create(token);
    }

    function wagered(address user, uint256 amount, uint256 GAME_ID, address token, uint256 partnerId) external override onlyGame {

        // add to list if new user
        if (userInfo[user].exists == false) {
            allUsers.push(user);
            userInfo[user].exists = true;
        }

        // increment total wagers placed
        unchecked {
            ++totalWagersPlaced;
        }

        if (token != address(0)) {

            // check if viewer exists
            address viewer = tokenToViewer[token];
            require(viewer != address(0), "Viewer does not exist");
            
            // pass through to token viewer
            ITokenWagerViewer(viewer).wagered(user, amount, GAME_ID, partnerId);
        
        } else {

            // increment total native Spent
            unchecked {
                
                // increment values by the amount of native spent
                totalWagered += amount;
                userInfo[user].totalWagered += amount;
                totalWageredForPartner[partnerId] += amount;
                userInfo[user].gameData[GAME_ID].totalWagered += amount;

                // increment total wagers placed
                ++userInfo[user].gameData[GAME_ID].numGamesPlayed;
            }

            // emit events for tracking
            emit Transfer(address(0), user, amount);
        }
    }

    function _create(address token) internal returns (address newViewer) {
        
        // create clone
        newViewer = Cloneable(viewerImplementation).clone();

        // push to array and add to mapping
        allTokenViewers.push(newViewer);
        tokenToViewer[token] = newViewer;

        // initialize clone
        ITokenWagerViewer(newViewer).__init__(token);
    }

    function listAllUsers() external view override returns (address[] memory) {
        return allUsers;
    }

    function totalUsers() external view returns (uint256) {
        return allUsers.length;
    }

    function totalNativeWagered(address user) external view returns (uint256) {
        return userInfo[user].totalWagered;
    }

    function getGameData(address user, uint256 GAME_ID) external view returns (uint256 _totalWagered, uint256 numGamesPlayed) {
        return (userInfo[user].gameData[GAME_ID].totalWagered, userInfo[user].gameData[GAME_ID].numGamesPlayed);
    }

    function batchGameData(address user, uint256[] calldata GAME_IDs) external view returns (uint256[] memory _totalWagered, uint256[] memory numGamesPlayed) {
        uint256 len = GAME_IDs.length;
        _totalWagered = new uint256[](len);
        numGamesPlayed = new uint256[](len);
        for (uint i = 0; i < len;) {
            _totalWagered[i] = userInfo[user].gameData[GAME_IDs[i]].totalWagered;
            numGamesPlayed[i] = userInfo[user].gameData[GAME_IDs[i]].numGamesPlayed;
            unchecked { ++i; }
        }
    }

    function getListOfTotalWageredByProject(uint256[] calldata projects) external view returns (uint256[] memory) {
        uint256 len = projects.length;
        uint256[] memory list = new uint256[](len);
        for (uint i = 0; i < len;) {
            list[i] = totalWageredForPartner[projects[i]];
            unchecked { ++i; }
        }
        return list;
    }

    function getListOfTotalWagered(address[] calldata users) external view returns (uint256[] memory) {
        uint256 len = users.length;
        uint256[] memory list = new uint256[](len);
        for (uint i = 0; i < len;) {
            list[i] = userInfo[users[i]].totalWagered;
            unchecked { ++i; }
        }
        return list;
    }

    function getListOfTotalWageredPaginated(uint256 startIndex, uint256 endIndex) external view returns (uint256[] memory) {
        if (endIndex > allUsers.length) {
            endIndex = allUsers.length;
        }
        uint256[] memory list = new uint256[](endIndex - startIndex);
        uint256 count;
        for (uint256 i = startIndex; i < endIndex;) {
            list[count] = userInfo[allUsers[i]].totalWagered;
            unchecked { ++i; ++count; }
        }
        return list;
    }

    function paginateAllUsers(uint256 startIndex, uint256 endIndex) public view returns (address[] memory) {
        if (endIndex > allUsers.length) {
            endIndex = allUsers.length;
        }
        address[] memory list = new address[](endIndex - startIndex);
        uint256 count;
        for (uint256 i = startIndex; i < endIndex;) {
            list[count] = allUsers[i];
            unchecked { ++i; ++count; }
        }
        return list;
    }



    // Token Calls
    function getTokenTotalWagered(address token) external view returns (uint256) {
        return IERC20(tokenToViewer[token]).totalSupply();
    }

    function getTokenTotalWageredForUser(address token, address user) external view returns (uint256) {
        return IERC20(tokenToViewer[token]).balanceOf(user);
    }

    function getGameDataToken(address token, address user, uint256 GAME_ID) external view returns (uint256 _totalWagered, uint256 numGamesPlayed) {
        return ITokenWagerViewer(tokenToViewer[token]).getGameData(user, GAME_ID);
    }

    function batchGameDataToken(address token, address user, uint256[] calldata GAME_IDs) external view returns (uint256[] memory _totalWagered, uint256[] memory numGamesPlayed) {
        return ITokenWagerViewer(tokenToViewer[token]).batchGameData(user, GAME_IDs);
    }

    function getListOfTotalWageredByProjectToken(address token, uint256[] calldata projects) external view returns (uint256[] memory) {
        return ITokenWagerViewer(tokenToViewer[token]).getListOfTotalWageredByProject(projects);
    }

    function getListOfTotalWageredToken(address token, address[] calldata users) external view returns (uint256[] memory) {
        return ITokenWagerViewer(tokenToViewer[token]).getListOfTotalWagered(users);
    }

    function getListOfTotalWageredPaginatedToken(address token, uint256 startIndex, uint256 endIndex) external view returns (uint256[] memory) {
        return ITokenWagerViewer(tokenToViewer[token]).getListOfTotalWageredPaginated(paginateAllUsers(startIndex, endIndex));
    }

}
设置
{
  "compilationTarget": {
    "contracts/UserTracker/UserInfo.sol": "UserInfo"
  },
  "evmVersion": "london",
  "libraries": {},
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "remappings": []
}
ABI
[{"inputs":[{"internalType":"address","name":"_viewerImp","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allTokenViewers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"allUsers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256[]","name":"GAME_IDs","type":"uint256[]"}],"name":"batchGameData","outputs":[{"internalType":"uint256[]","name":"_totalWagered","type":"uint256[]"},{"internalType":"uint256[]","name":"numGamesPlayed","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256[]","name":"GAME_IDs","type":"uint256[]"}],"name":"batchGameDataToken","outputs":[{"internalType":"uint256[]","name":"_totalWagered","type":"uint256[]"},{"internalType":"uint256[]","name":"numGamesPlayed","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"createViewer","outputs":[{"internalType":"address","name":"viewer","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"GAME_ID","type":"uint256"}],"name":"getGameData","outputs":[{"internalType":"uint256","name":"_totalWagered","type":"uint256"},{"internalType":"uint256","name":"numGamesPlayed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"GAME_ID","type":"uint256"}],"name":"getGameDataToken","outputs":[{"internalType":"uint256","name":"_totalWagered","type":"uint256"},{"internalType":"uint256","name":"numGamesPlayed","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"users","type":"address[]"}],"name":"getListOfTotalWagered","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"projects","type":"uint256[]"}],"name":"getListOfTotalWageredByProject","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256[]","name":"projects","type":"uint256[]"}],"name":"getListOfTotalWageredByProjectToken","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"endIndex","type":"uint256"}],"name":"getListOfTotalWageredPaginated","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"endIndex","type":"uint256"}],"name":"getListOfTotalWageredPaginatedToken","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address[]","name":"users","type":"address[]"}],"name":"getListOfTotalWageredToken","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"getTokenTotalWagered","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"user","type":"address"}],"name":"getTokenTotalWageredForUser","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"listAllUsers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"contract IGovernanceManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"startIndex","type":"uint256"},{"internalType":"uint256","name":"endIndex","type":"uint256"}],"name":"paginateAllUsers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"implementation","type":"address"}],"name":"setViewerImplementation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenToViewer","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"totalNativeWagered","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalUsers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWagered","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"totalWageredForPartner","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalWagersPlaced","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"viewerImplementation","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"GAME_ID","type":"uint256"},{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"partnerId","type":"uint256"}],"name":"wagered","outputs":[],"stateMutability":"nonpayable","type":"function"}]