Custom Proposals

The Player Pool proposal system is designed to be highly flexible, allowing any smart contract deployed on the Base network to be submitted as a proposal.

This open architecture encourages innovation and creativity in determining how Player Pool funds are utilized, with the most engaging and well-designed proposals naturally attracting more support from the community. Proposals that demonstrate particular value or widespread community adoption may be selected for integration into our proposal launchpad, making them easily accessible to future users.

The Player Pool implements a "push-pull" pattern for transferring funds. When a proposal wins the Player Pool round, the Monk Game Hub automatically pushes the accumulated Player Pool funds to the winning proposal's contract address. The proposal contract then takes responsibility for handling these funds through an "execution function".

To maximize community adoption and trust, we strongly recommend implementing the execution function as a public, permissionless method without ownership restrictions or access controls. This approach allows for full transparency and ensures that proposal funds are used as intended.

For example, here's a proposal that creates a coinflip game with the player pool funds:

/**
 * This proposal contract creates a coinflip game with the Player Pool funds.
 */

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

// minimal interface for the Monk Coinflip contract
interface ICoinflip {
  function createGame(uint256 betAmount, bool creatorChoice, address giftedPlayer)
    external
    payable;
}

contract CoinflipThePool {
  IERC20 public constant MonkToken = IERC20(0xBE8DfC6661fAfAA4445Eb952586c0D347EaCF048);
  ICoinflip public constant Coinflip = ICoinflip(0x39B1aB5f7De19B960bf53Fb87B9eC030D2d1b747);
  address public constant MonkGameHub = 0x68275f05c45AbF95ee45C044c54BdF93560e333B;

  address public immutable participant;
  bool public immutable sideChoice;

  constructor(address _participant, bool _sideChoice) {
    participant = _participant;
    sideChoice = _sideChoice;
  }

  function _min(uint256 a, uint256 b) internal pure returns (uint256) {
    return a < b ? a : b;
  }

  // permissionless point of fund execution
  function execute() external {
    uint256 amount = MonkToken.balanceOf(address(this));
    require(amount > 0, "Nothing to flip");

    uint256 maxAmount = MonkToken.balanceOf(MonkGameHub) / 100; // coinflip max bet is 1% of the bankroll

    Coinflip.createGame(_min(amount, maxAmount), sideChoice, participant);
  }
}

In the future, custom proposals will be able to query and consume data from the Monk Data Oracles.

Last updated