GushProtocol
0x1f1675daf8d1f6a145837743f3a63f95cdedb926
Verification
Verified
v0.8.28+commit.7893614a
Type
Contract
9,100 bytes
ABI entries
51
16 read · 16 write
License
none
Contract information
- Address
- 0x1f1675daf8d1f6a145837743f3a63f95cdedb926
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.28+commit.7893614a
- Optimization
- Enabled
- Creator
- 0x4CD37cC192…7508353162
- Creation tx
- 0x8bca36500a…cb39e4a5ca
Token
Not a token
This contract does not expose ERC-20 metadata.
Read contract (16)
BPS() → uint256
DEPTH_UNIT() → uint256
WELLHEAD_BURN() → address
commodities(uint256) → string, uint256, uint256, uint256, uint256, uint256, bool
commodityCount() → uint256
emissionBudget() → uint256
feeRecipient() → address
gush() → address
oracle() → address
owner() → address
pendingGush(uint256) → uint256
settlementFeeBps() → uint256
wellCount() → uint256
wellRatePerSec(uint256) → uint256
wells(uint256) → uint256, address, uint256, uint256, uint256, bool
wellsRemaining(uint256) → uint256
Events (15)
BaseRateSetBudgetFundedBudgetReclaimedClaimPriceSetCommodityActiveCommodityAddedDeepenedFeeRecipientSetGushedOracleSetOwnershipTransferredSettlementFeeSetVolatilitySetWellClaimedWellTransferred
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "gush_",
"type": "address"
},
{
"internalType": "address",
"name": "feeRecipient_",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"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": "uint256",
"name": "id",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "baseRatePerSec",
"type": "uint256"
}
],
"name": "BaseRateSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "BudgetFunded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "BudgetReclaimed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "claimPriceWei",
"type": "uint256"
}
],
"name": "ClaimPriceSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"indexed": false,
"internalType": "bool",
"name": "active",
"type": "bool"
}
],
"name": "CommodityActive",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"indexed": false,
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"indexed": false,
"internalType": "uint256",
"name": "wellSupply",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "claimPriceWei",
"type": "uint256"
}
],
"name": "CommodityAdded",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "wellId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "gushBurned",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "newDepth",
"type": "uint256"
}
],
"name": "Deepened",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "recipient",
"type": "address"
}
],
"name": "FeeRecipientSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "wellId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "toOperator",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "fee",
"type": "uint256"
}
],
"name": "Gushed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "oracle",
"type": "address"
}
],
"name": "OracleSet",
"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": false,
"internalType": "uint256",
"name": "bps",
"type": "uint256"
}
],
"name": "SettlementFeeSet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "id",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "volBps",
"type": "uint256"
}
],
"name": "VolatilitySet",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "wellId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "uint256",
"name": "commodityId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "pricePaid",
"type": "uint256"
}
],
"name": "WellClaimed",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "uint256",
"name": "wellId",
"type": "uint256"
},
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "WellTransferred",
"type": "event"
},
{
"inputs": [],
"name": "BPS",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "DEPTH_UNIT",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "WELLHEAD_BURN",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "uint256",
"name": "wellSupply",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "claimPriceWei",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "baseRatePerSec",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "volBps",
"type": "uint256"
}
],
"name": "addCommodity",
"outputs": [
{
"internalType": "uint256",
"name": "id",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "commodityId",
"type": "uint256"
}
],
"name": "claimWell",
"outputs": [
{
"internalType": "uint256",
"name": "wellId",
"type": "uint256"
}
],
"stateMutability": "payable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "commodities",
"outputs": [
{
"internalType": "string",
"name": "symbol",
"type": "string"
},
{
"internalType": "uint256",
"name": "wellSupply",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "wellsClaimed",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "claimPriceWei",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "baseRatePerSec",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "volBps",
"type": "uint256"
},
{
"internalType": "bool",
"name": "active",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "commodityCount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "wellId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "gushAmount",
"type": "uint256"
}
],
"name": "deepenWell",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "emissionBudget",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "feeRecipient",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "fundBudget",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "gush",
"outputs": [
{
"internalType": "contract IERC20",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "wellId",
"type": "uint256"
}
],
"name": "gushWell",
"outputs": [
{
"internalType": "uint256",
"name": "toOperator",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "oracle",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "wellId",
"type": "uint256"
}
],
"name": "pendingGush",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "reclaimBudget",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "commodityId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "baseRatePerSec",
"type": "uint256"
}
],
"name": "setBaseRate",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "commodityId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "claimPriceWei",
"type": "uint256"
}
],
"name": "setClaimPrice",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "commodityId",
"type": "uint256"
},
{
"internalType": "bool",
"name": "active",
"type": "bool"
}
],
"name": "setCommodityActive",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "recipient",
"type": "address"
}
],
"name": "setFeeRecipient",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "oracle_",
"type": "address"
}
],
"name": "setOracle",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "bps",
"type": "uint256"
}
],
"name": "setSettlementFee",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "commodityId",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "volBps",
"type": "uint256"
}
],
"name": "setVolatility",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "settlementFeeBps",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "wellId",
"type": "uint256"
},
{
"internalType": "address",
"name": "to",
"type": "address"
}
],
"name": "transferWell",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "wellCount",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "wellId",
"type": "uint256"
}
],
"name": "wellRatePerSec",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"name": "wells",
"outputs": [
{
"internalType": "uint256",
"name": "commodityId",
"type": "uint256"
},
{
"internalType": "address",
"name": "operator",
"type": "address"
},
{
"internalType": "uint256",
"name": "depth",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "accrued",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "lastUpdate",
"type": "uint256"
},
{
"internalType": "bool",
"name": "exists",
"type": "bool"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "commodityId",
"type": "uint256"
}
],
"name": "wellsRemaining",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
/*
. GUSH PROTOCOL — The Rig.
/ \\ Claim a well. Run the bit. Let it gush.
/ . \\
/ o \\ Wellhead → wallet, in three onchain stages:
(___|___)
| 01 CLAIM A WELL Each well is a unique onchain slot tied to a
| real extractive market (WTI, BRENT, NATGAS, COPPER, URANIUM…).
| Supply of wells per commodity is FIXED. Early claimers drill
| the richest fields; latecomers drill what's left of Alberta.
|
| 02 RUN THE BIT Wells produce $GUSH while you operate them.
| Output tracks the real volatility of the underlying commodity
| — a hot tape multiplies throughput; a quiet tape seeps slow.
|
v 03 LET IT GUSH Extracted barrels settle to $GUSH at the
~~~~~~~~~ wellhead. The protocol fee recipient takes a cut of every
~ RESERVOIR settlement to fund the board. Burn $GUSH to DEEPEN a well and
~~~~~~~~~ raise its base output — the only sink in the system, and it's
a drill bit.
NON-RUGGABLE BY CONSTRUCTION:
• A well, once claimed, belongs to its operator forever. The owner has NO
path to seize, freeze, or reassign a well, and can NEVER block `gush()`
or `deepen()`. Wells are freely transferable by their operator.
• $GUSH payouts come ONLY from a pre-funded emission budget. The protocol
never mints. If the budget empties, wells simply pay what remains.
• ETH from claims is forwarded to the immutable fee recipient on receipt —
it is never custodied here.
• The owner can only: register commodities, tune volatility / base rates /
claim prices, and reclaim UNALLOCATED emission budget. Nothing else.
*/
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
/// @title GushProtocol
/// @notice The Rig: claim wells on extractive markets, run the bit, let it gush.
contract GushProtocol is Ownable {
using SafeERC20 for IERC20;
/// @notice The reward token, $GUSH. Wells pay out from a pre-funded budget of it.
IERC20 public immutable gush;
/// @notice Where well-claim ETH is forwarded (e.g. GushFeeRouter). Owner-set routing.
address public feeRecipient;
/// @notice Address permitted to push live volatility multipliers (the "board" oracle).
address public oracle;
/// @dev Dead address for the burn sink. $GUSH sent here can never return.
address public constant WELLHEAD_BURN = 0x000000000000000000000000000000000000dEaD;
/// @dev Depth is measured in the same 18-dec units as burned $GUSH.
/// Base output doubles for every DEPTH_UNIT of $GUSH burned into a well.
uint256 public constant DEPTH_UNIT = 100 ether;
/// @dev Basis-points denominator.
uint256 public constant BPS = 10_000;
/// @notice Cut of every settlement (in $GUSH) routed to the fee recipient. Max 20%.
uint256 public settlementFeeBps = 1_000; // 10%
struct Commodity {
string symbol; // "WTI", "BRENT", "NATGAS", "COPPER", "URANIUM", ...
uint256 wellSupply; // max wells that can ever be claimed on this market
uint256 wellsClaimed; // wells claimed so far
uint256 claimPriceWei; // ETH cost to claim one well here
uint256 baseRatePerSec; // $GUSH/sec at depth 0, volatility 1x
uint256 volBps; // volatility multiplier; 10_000 = 1x, 20_000 = 2x (hot tape)
bool active; // whether new wells may be claimed
}
struct Well {
uint256 commodityId;
address operator; // current owner of the well
uint256 depth; // extra depth from burns (18-dec, same units as $GUSH)
uint256 accrued; // $GUSH accounted but not yet paid out
uint256 lastUpdate; // last accrual timestamp
bool exists;
}
Commodity[] public commodities;
Well[] public wells;
/// @notice $GUSH reserved as emission budget (funded by anyone via fundBudget).
uint256 public emissionBudget;
// ── events ──────────────────────────────────────────────────────────────
event CommodityAdded(uint256 indexed id, string symbol, uint256 wellSupply, uint256 claimPriceWei);
event VolatilitySet(uint256 indexed id, uint256 volBps);
event BaseRateSet(uint256 indexed id, uint256 baseRatePerSec);
event ClaimPriceSet(uint256 indexed id, uint256 claimPriceWei);
event CommodityActive(uint256 indexed id, bool active);
event FeeRecipientSet(address indexed recipient);
event OracleSet(address indexed oracle);
event SettlementFeeSet(uint256 bps);
event BudgetFunded(address indexed from, uint256 amount);
event BudgetReclaimed(address indexed to, uint256 amount);
event WellClaimed(uint256 indexed wellId, uint256 indexed commodityId, address indexed operator, uint256 pricePaid);
event WellTransferred(uint256 indexed wellId, address indexed from, address indexed to);
event Gushed(uint256 indexed wellId, address indexed operator, uint256 toOperator, uint256 fee);
event Deepened(uint256 indexed wellId, address indexed operator, uint256 gushBurned, uint256 newDepth);
constructor(address gush_, address feeRecipient_) Ownable(msg.sender) {
require(gush_ != address(0), "zero gush");
require(feeRecipient_ != address(0), "zero recipient");
gush = IERC20(gush_);
feeRecipient = feeRecipient_;
oracle = msg.sender;
}
// ──────────────────────────────── Admin ──────────────────────────────────
/// @notice Register a new extractive market with a fixed well supply.
function addCommodity(
string calldata symbol,
uint256 wellSupply,
uint256 claimPriceWei,
uint256 baseRatePerSec,
uint256 volBps
) external onlyOwner returns (uint256 id) {
require(wellSupply > 0, "zero supply");
require(volBps > 0, "zero vol");
id = commodities.length;
commodities.push(
Commodity({
symbol: symbol,
wellSupply: wellSupply,
wellsClaimed: 0,
claimPriceWei: claimPriceWei,
baseRatePerSec: baseRatePerSec,
volBps: volBps,
active: true
})
);
emit CommodityAdded(id, symbol, wellSupply, claimPriceWei);
}
/// @notice Push a live volatility multiplier for a market. Oracle or owner only.
/// Accrues every subsequent second at the new rate; past accrual is safe
/// because wells checkpoint their accrual before any rate change matters.
function setVolatility(uint256 commodityId, uint256 volBps) external {
require(msg.sender == oracle || msg.sender == owner(), "not oracle");
require(volBps > 0, "zero vol");
commodities[commodityId].volBps = volBps;
emit VolatilitySet(commodityId, volBps);
}
function setBaseRate(uint256 commodityId, uint256 baseRatePerSec) external onlyOwner {
commodities[commodityId].baseRatePerSec = baseRatePerSec;
emit BaseRateSet(commodityId, baseRatePerSec);
}
function setClaimPrice(uint256 commodityId, uint256 claimPriceWei) external onlyOwner {
commodities[commodityId].claimPriceWei = claimPriceWei;
emit ClaimPriceSet(commodityId, claimPriceWei);
}
function setCommodityActive(uint256 commodityId, bool active) external onlyOwner {
commodities[commodityId].active = active;
emit CommodityActive(commodityId, active);
}
function setFeeRecipient(address recipient) external onlyOwner {
require(recipient != address(0), "zero recipient");
feeRecipient = recipient;
emit FeeRecipientSet(recipient);
}
function setOracle(address oracle_) external onlyOwner {
require(oracle_ != address(0), "zero oracle");
oracle = oracle_;
emit OracleSet(oracle_);
}
function setSettlementFee(uint256 bps) external onlyOwner {
require(bps <= 2_000, "fee too high"); // hard cap 20%
settlementFeeBps = bps;
emit SettlementFeeSet(bps);
}
/// @notice Top up the $GUSH emission budget. Anyone may fund the board.
function fundBudget(uint256 amount) external {
require(amount > 0, "zero amount");
gush.safeTransferFrom(msg.sender, address(this), amount);
emissionBudget += amount;
emit BudgetFunded(msg.sender, amount);
}
/// @notice Reclaim UNALLOCATED emission budget only — never an operator's payout.
function reclaimBudget(address to, uint256 amount) external onlyOwner {
require(to != address(0), "zero to");
require(amount <= emissionBudget, "exceeds budget");
emissionBudget -= amount;
gush.safeTransfer(to, amount);
emit BudgetReclaimed(to, amount);
}
// ─────────────────────────────── The Rig ─────────────────────────────────
/// @notice Claim the next available well on a commodity. Pays ETH to the wellhead.
/// @dev Overpayment is refunded. ETH is forwarded to the fee recipient on receipt.
function claimWell(uint256 commodityId) external payable returns (uint256 wellId) {
Commodity storage c = commodities[commodityId];
require(c.active, "market closed");
require(c.wellsClaimed < c.wellSupply, "field depleted");
require(msg.value >= c.claimPriceWei, "underpaid");
c.wellsClaimed += 1;
wellId = wells.length;
wells.push(
Well({
commodityId: commodityId,
operator: msg.sender,
depth: 0,
accrued: 0,
lastUpdate: block.timestamp,
exists: true
})
);
uint256 price = c.claimPriceWei;
// Forward exactly the claim price to the wellhead; refund any overpayment.
if (price > 0) {
(bool ok,) = feeRecipient.call{value: price}("");
require(ok, "wellhead send failed");
}
uint256 refund = msg.value - price;
if (refund > 0) {
(bool ok2,) = msg.sender.call{value: refund}("");
require(ok2, "refund failed");
}
emit WellClaimed(wellId, commodityId, msg.sender, price);
}
/// @notice Settle extracted barrels to $GUSH. Callable only by the well operator.
/// The fee recipient takes `settlementFeeBps` of the payout.
function gushWell(uint256 wellId) external returns (uint256 toOperator) {
Well storage w = wells[wellId];
require(w.exists, "no well");
require(w.operator == msg.sender, "not operator");
_accrue(wellId);
uint256 owed = w.accrued;
if (owed == 0) {
emit Gushed(wellId, msg.sender, 0, 0);
return 0;
}
// Pay only from the funded budget; never mint, never dip past budget.
uint256 pay = owed > emissionBudget ? emissionBudget : owed;
w.accrued = owed - pay; // carry forward any unpayable remainder
emissionBudget -= pay;
uint256 fee = (pay * settlementFeeBps) / BPS;
toOperator = pay - fee;
if (fee > 0) gush.safeTransfer(feeRecipient, fee);
if (toOperator > 0) gush.safeTransfer(msg.sender, toOperator);
emit Gushed(wellId, msg.sender, toOperator, fee);
}
/// @notice Burn $GUSH into a well to DEEPEN it and raise its base output.
/// The only sink in the system. Burned $GUSH is sent to 0xdead.
function deepenWell(uint256 wellId, uint256 gushAmount) external {
Well storage w = wells[wellId];
require(w.exists, "no well");
require(w.operator == msg.sender, "not operator");
require(gushAmount > 0, "zero burn");
// Checkpoint accrual at the OLD rate before depth changes.
_accrue(wellId);
// Real burn: move $GUSH out of circulation to the dead address.
gush.safeTransferFrom(msg.sender, WELLHEAD_BURN, gushAmount);
w.depth += gushAmount;
emit Deepened(wellId, msg.sender, gushAmount, w.depth);
}
/// @notice Transfer a well to another operator. Settles nothing; pending accrual
/// travels with the well. Only the current operator may transfer.
function transferWell(uint256 wellId, address to) external {
Well storage w = wells[wellId];
require(w.exists, "no well");
require(w.operator == msg.sender, "not operator");
require(to != address(0), "zero to");
_accrue(wellId); // freeze accrual to the moment of transfer
w.operator = to;
emit WellTransferred(wellId, msg.sender, to);
}
// ─────────────────────────────── Accrual ─────────────────────────────────
function _rate(Well storage w) internal view returns (uint256) {
Commodity storage c = commodities[w.commodityId];
// base * (1 + depth/DEPTH_UNIT) * volatility
uint256 depthScaled = c.baseRatePerSec * (DEPTH_UNIT + w.depth) / DEPTH_UNIT;
return depthScaled * c.volBps / BPS;
}
function _accrue(uint256 wellId) internal {
Well storage w = wells[wellId];
if (block.timestamp <= w.lastUpdate) return;
uint256 elapsed = block.timestamp - w.lastUpdate;
w.accrued += elapsed * _rate(w);
w.lastUpdate = block.timestamp;
}
// ─────────────────────────────── Views ───────────────────────────────────
function commodityCount() external view returns (uint256) {
return commodities.length;
}
function wellCount() external view returns (uint256) {
return wells.length;
}
/// @notice Current output of a well in $GUSH per second (depth × volatility applied).
function wellRatePerSec(uint256 wellId) external view returns (uint256) {
return _rate(wells[wellId]);
}
/// @notice Pending $GUSH ready to gush from a well, live to `block.timestamp`.
function pendingGush(uint256 wellId) external view returns (uint256) {
Well storage w = wells[wellId];
if (!w.exists) return 0;
uint256 acc = w.accrued;
if (block.timestamp > w.lastUpdate) {
acc += (block.timestamp - w.lastUpdate) * _rate(w);
}
return acc;
}
/// @notice How many wells remain claimable on a commodity.
function wellsRemaining(uint256 commodityId) external view returns (uint256) {
Commodity storage c = commodities[commodityId];
return c.wellSupply - c.wellsClaimed;
}
}
Chain explorer2035msChain node87ms