Skip to content
Protocol contracts not yet configured for this build
Enter app

Architecture

BuybackExecutor

Holds the 60% allocation, buys PLOUTO on the canonical route, and retires everything it acquires in the same transaction.

Immutables

solidity
IPloutoRegistry public immutable registry;IPonsV2Factory  public immutable ponsFactory;IPoolManager    public immutable poolManager;address         public immutable ponsMemeHook;      // read from factory.memeHook()uint256         public immutable expectedChainId; address public constant DEAD_ADDRESS = 0x000000000000000000000000000000000000dEaD;

Safety parameters

Adjustable by DEFAULT_ADMIN_ROLE, with sane defaults:

ParameterDefaultPurpose
maxEthPerExecution0.25 ETHHard cap on a single trade.
maxBudgetShareBps2500Cap as a share of available budget.
maxPriceImpactBps500On-chain tolerance versus pre-trade spot.
minEthPerExecution0.001 ETHDust floor.

setSafetyParams validates its inputs and reverts with InvalidParams on nonsense (zero caps, bps over 10,000, min above max).

Execution

solidity
function executeBuyback(uint256 ethIn, uint256 minTokensOut, uint256 deadline)    external onlyRole(KEEPER_ROLE) nonReentrant whenNotPaused    returns (uint256 tokensRetired)

In order:

  1. block.chainid == expectedChainId, else WrongChain.
  2. block.timestamp <= deadline, else DeadlinePassed.
  3. minTokensOut != 0, else ZeroMinTokensOut.
  4. Registry initialized, else NotInitialized.
  5. Spend bounds — NoBudget, AmountTooSmall, ExceedsBudget, ExceedsPerExecutionCap, ExceedsBudgetShare.
  6. Factory record matches the registry, else RouteMismatch.
  7. Budget debited before the route runs.
  8. Route by phase.
  9. Acquired amount measured by balance delta; InsufficientOutput if short.
  10. Retire.
  11. Record and emit.

The residual rule

solidity
uint256 shareCap = (budget * maxBudgetShareBps) / BPS;// Always allow draining a budget at or below the per-execution cap, otherwise a// small residual balance could never be spent.if (ethIn > shareCap && ethIn != budget) revert ExceedsBudgetShare(ethIn, shareCap);

Without this, a budget smaller than the share cap would be permanently unspendable.

Retirement

solidity
uint256 supplyBefore = _totalSupply(token);(bool ok,) = token.call(abi.encodeWithSignature("burn(uint256)", amount));if (ok && _totalSupply(token) + amount == supplyBefore) {    totalPloutoBurned += amount;    return true;}IERC20(token).safeTransfer(DEAD_ADDRESS, amount);totalPloutoSentToDead += amount;return false;

The supply is checked, not assumed. A burn that succeeds without reducing supply falls through to the dead address and is reported as such.

Price impact, enforced on chain

Both routes compute an ideal output from pre-trade spot and require the realised output to land within tolerance. Pre-graduation that comes from the curve reserves; post-graduation from sqrtPriceX96 read out of PoolManager storage via extsload.

This is what makes the keeper untrusted: minTokensOut = 1 still cannot execute a trade worse than maxPriceImpactBps.

Donations

solidity
receive() external payable {    if (msg.sender == address(poolManager)) return;   // v4 settlement refund    totalDonationsReceived += msg.value;    emit DonationReceived(msg.sender, msg.value);}

Donated ETH is never spendable as budget.