RavenhoodRitual

0xf65227639636288f3ec7d1368dbf6e6f7a99b533

Verification
Verified
v0.8.27+commit.40a35a09
Type
Contract
6,409 bytes
ABI entries
18
9 read · 4 write
License
none

Contract information

Address
0xf65227639636288f3ec7d1368dbf6e6f7a99b533
Chain
Robinhood Chain (4663)
Compiler
v0.8.27+commit.40a35a09
Optimization
Enabled
Creation tx
0x4ec0149bff…68f0524199

Token

Not a token

This contract does not expose ERC-20 metadata.

Read contract (9)

FACTORY()address
POSITION_MANAGER()address
RAVENHOOD()address
VAULT()address
WETH()address
nextBurnTime()uint256
nextChaosTime()uint256
owner()address
pool()address

Events (3)

BurnExecutedOwnershipTransferredStabilityForged

ABI

[
  {
    "inputs": [],
    "stateMutability": "nonpayable",
    "type": "constructor"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "uint256",
        "name": "voidRate",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "wethToOwner",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "wethBuyback",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "rvnBurned",
        "type": "uint256"
      }
    ],
    "name": "BurnExecuted",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": true,
        "internalType": "address",
        "name": "user",
        "type": "address"
      },
      {
        "indexed": true,
        "internalType": "address",
        "name": "newOwner",
        "type": "address"
      }
    ],
    "name": "OwnershipTransferred",
    "type": "event"
  },
  {
    "anonymous": false,
    "inputs": [
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "wethIn",
        "type": "uint256"
      },
      {
        "indexed": false,
        "internalType": "uint256",
        "name": "rvnBurned",
        "type": "uint256"
      }
    ],
    "name": "StabilityForged",
    "type": "event"
  },
  {
    "inputs": [],
    "name": "FACTORY",
    "outputs": [
      {
        "internalType": "contract IUniswapV3Factory",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "POSITION_MANAGER",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "RAVENHOOD",
    "outputs": [
      {
        "internalType": "contract Ravenhood",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "VAULT",
    "outputs": [
      {
        "internalType": "contract RavenhoodVault",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "WETH",
    "outputs": [
      {
        "internalType": "contract IWETH",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "feedTheRaven",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "intoTheVoid",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "nextBurnTime",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "nextChaosTime",
    "outputs": [
      {
        "internalType": "uint256",
        "name": "",
        "type": "uint256"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "owner",
    "outputs": [
      {
        "internalType": "address",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [],
    "name": "pool",
    "outputs": [
      {
        "internalType": "contract IUniswapV3Pool",
        "name": "",
        "type": "address"
      }
    ],
    "stateMutability": "view",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "address",
        "name": "newOwner",
        "type": "address"
      }
    ],
    "name": "transferOwnership",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "inputs": [
      {
        "internalType": "int256",
        "name": "amount0",
        "type": "int256"
      },
      {
        "internalType": "int256",
        "name": "amount1",
        "type": "int256"
      },
      {
        "internalType": "bytes",
        "name": "data",
        "type": "bytes"
      }
    ],
    "name": "uniswapV3SwapCallback",
    "outputs": [],
    "stateMutability": "nonpayable",
    "type": "function"
  },
  {
    "stateMutability": "payable",
    "type": "receive"
  }
]

Source code

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

import {Owned} from "solmate/src/auth/Owned.sol";
import {Ravenhood} from "./RavenhoodToken.sol";
import {RavenhoodVault} from "./RavenhoodVault.sol";

import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {IWETH} from "./interfaces/IWETH.sol";
import {IUniswapV3Factory} from "./interfaces/IUniswapV3Factory.sol";
import {IUniswapV3Pool} from "./interfaces/IUniswapV3Pool.sol";

contract RavenhoodRitual is Owned {
    /// @dev Robinhood Chain (chainId 4663) — Uniswap V3. Verified on-chain 2026-07-03 (see CLAUDE.md).
    /// WETH = wrapped native (the chain's gas token is ETH). POSITION_MANAGER = Uniswap V3
    /// NonfungiblePositionManager; FACTORY = UniswapV3Factory (also the CREATE2 pool deployer).
    IWETH public constant WETH = IWETH(0x0Bd7D308f8E1639FAb988df18A8011f41EAcAD73);
    address public constant POSITION_MANAGER = 0x73991a25C818Bf1f1128dEAaB1492D45638DE0D3;
    IUniswapV3Factory public constant FACTORY = IUniswapV3Factory(0x1f7d7550B1b028f7571E69A784071F0205FD2EfA);

    /// @dev create when deploying this contract
    Ravenhood public immutable RAVENHOOD;
    RavenhoodVault public immutable VAULT;

    IUniswapV3Pool public pool;
    uint256 public nextBurnTime;
    uint256 public nextChaosTime;

    /// @dev token info
    uint256 private constant TOKEN_SUPPLY = 100_000_000e18;
    uint256 private constant BENCHMARK_SUPPLY = TOKEN_SUPPLY / 100;

    /// @dev fee of the pool which nft locked in RavenhoodVault contract is created
    uint24 private constant POOL_FEE = 10_000;

    /// @dev minimum WETH balance for feedTheRaven() to run
    uint256 private constant MIN_RAVEN_MEAL = 0.01e18;

    /// @dev uniswap v3 constants
    uint160 private constant MIN_SQRT_RATIO = 4295128739;
    uint160 private constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342;

    /// @dev token0 in liquidity pool
    address private token0;

    event BurnExecuted(uint256 indexed voidRate, uint256 wethToOwner, uint256 wethBuyback, uint256 rvnBurned);
    event StabilityForged(uint256 wethIn, uint256 rvnBurned);

    constructor() Owned(msg.sender) {
        RAVENHOOD = new Ravenhood(msg.sender, TOKEN_SUPPLY);
        VAULT = new RavenhoodVault(msg.sender, POSITION_MANAGER);
        RAVENHOOD.renounceOwnership();
    }

    receive() external payable {
        WETH.deposit{value: msg.value}();
    }

    function intoTheVoid() external {
        uint256 burnedSupply = RAVENHOOD.balanceOf(address(0));
        uint256 voidRate = burnedSupply / BENCHMARK_SUPPLY;

        require(voidRate < 90, "burns complete");

        uint256 interval = 4 hours;
        if (voidRate >= 5)  interval += 2 hours;
        if (voidRate >= 10) interval += 2 hours;
        if (voidRate >= 15) interval += 2 hours;
        if (voidRate >= 20) interval += 2 hours;
        if (voidRate >= 25) interval += 2 hours;
        if (voidRate >= 30) interval += 2 hours;
        if (voidRate >= 35) interval += 2 hours;
        if (voidRate >= 40) interval += 2 hours;
        if (voidRate >= 45) interval += 2 hours;
        if (voidRate >= 50) interval += 2 hours;
        if (voidRate >= 55) interval += 2 hours;
        if (voidRate >= 60) interval += 2 hours;
        if (voidRate >= 65) interval += 2 hours;
        if (voidRate >= 70) interval += 2 hours;
        if (voidRate >= 75) interval += 2 hours;
        if (voidRate >= 80) interval += 2 hours;
        if (voidRate >= 85) interval += 2 hours;

        require(block.timestamp >= nextBurnTime, "burn not ready");
        nextBurnTime = block.timestamp + interval;

        uint256 wethGain = WETH.balanceOf(address(this));
        VAULT.claimBurn();

        wethGain = WETH.balanceOf(address(this)) - wethGain;
        uint256 wethToOwner;
        uint256 wethBuyback;
        if (wethGain > 0) {
            if (voidRate < 25) {
                wethToOwner = wethGain;
                WETH.transfer(owner, wethGain);
            } else if (voidRate < 50) {
                uint256 ownerShare = wethGain / 2;
                wethToOwner = ownerShare;
                wethBuyback = wethGain - ownerShare;
                WETH.transfer(owner, ownerShare);
                _ensurePool();
                swap(address(WETH), address(RAVENHOOD), wethGain - ownerShare);
            } else {
                wethBuyback = wethGain;
                _ensurePool();
                swap(address(WETH), address(RAVENHOOD), wethGain);
            }
        }

        uint256 ravenhoodBalance = RAVENHOOD.balanceOf(address(this));
        if (ravenhoodBalance > 0) RAVENHOOD.transfer(address(0), ravenhoodBalance);
        emit BurnExecuted(voidRate, wethToOwner, wethBuyback, ravenhoodBalance);
    }

    function feedTheRaven() external {
        require(block.timestamp >= nextChaosTime, "chaos not ready");
        if (VAULT.nftId() == 0) return;
        VAULT.claimFees();
        // 0.01 WETH (~mid-double-digit USD) — enough to make the 3x churn meaningful.
        // (The old 1e18 floor was priced for MON at ~$0.03; 1 WETH would gate the
        // rite behind ~$1.7k of accrued fees.)
        require(WETH.balanceOf(address(this)) >= MIN_RAVEN_MEAL, "insufficient WETH");
        nextChaosTime = block.timestamp + 1 hours;
        if (address(pool) == address(0)) {
            pool = IUniswapV3Pool(FACTORY.getPool(address(WETH), address(RAVENHOOD), POOL_FEE));
            require(address(pool) != address(0), "pool not found");
            token0 = pool.token0();
        }

        uint256 rvnBurned = RAVENHOOD.balanceOf(address(this));
        if (rvnBurned > 0) RAVENHOOD.transfer(address(0), rvnBurned);

        uint256 wethIn = WETH.balanceOf(address(this));
        uint256 balance;
        for (uint256 i; i < 3; i++) {
            balance = WETH.balanceOf(address(this));
            if (balance > 0) swap(address(WETH), address(RAVENHOOD), balance);
            balance = RAVENHOOD.balanceOf(address(this));
            if (balance > 0) swap(address(RAVENHOOD), address(WETH), balance);
        }
        emit StabilityForged(wethIn, rvnBurned);
    }

    function uniswapV3SwapCallback(int256 amount0, int256 amount1, bytes calldata data) external {
        require(msg.sender == address(pool), "unauthorized");
        bool zeroForOne = data.length > 0;
        address token = zeroForOne ? token0 : token0 == address(WETH) ? address(RAVENHOOD) : address(WETH);
        uint256 amount = zeroForOne ? uint256(amount0) : uint256(amount1);
        IERC20(token).transfer(address(pool), amount);
    }

    function _ensurePool() private {
        if (address(pool) == address(0)) {
            pool = IUniswapV3Pool(FACTORY.getPool(address(WETH), address(RAVENHOOD), POOL_FEE));
            require(address(pool) != address(0), "pool not found");
            token0 = pool.token0();
        }
    }

    function swap(address tokenIn, address tokenOut, uint256 amount) private {
        if (amount == 0) return;
        bool zeroForOne = tokenIn < tokenOut;
        uint160 sqrt = zeroForOne ? MIN_SQRT_RATIO + 1 : MAX_SQRT_RATIO - 1;
        // solhint-disable-next-line no-empty-blocks
        try pool.swap(address(this), zeroForOne, int256(amount), sqrt, zeroForOne ? bytes("1") : bytes("")) {} catch {}
    }
}
Chain explorer3427msChain node77ms