The REDIF system, without the hand-waving.

REDIF trades in a stock-paired pool on Robinhood Chain. Every 2% trading fee is accounted for onchain: 0.30% to the launch protocol, 0.85% to the injection fund, and 0.85% to the project treasury. Any wallet can trigger a guarded liquidity injection. A 6-of-10 signed oracle protects the permanent vault's execution price. Separately, the fixed locker owner must call eternallyLock() before day 30 if REDIF passes a $10M market cap.

System map

From a trade to permanently owned liquidity.

01Trade

A buy or sell in the REDIF stock-paired pool charges the fixed 2% trading fee. The launch protocol accounts for the project share before it becomes claimable.

02Receiver

Claims actual receipts from escrow, verifies what reached the contract, and separates the project share into a 50% injection budget and 50% treasury balance.

03Oracle

Ten approved reporters sign time-limited reference ticks. Six matching signatures are required before the vault accepts the pool state for an injection.

04Vault

Uses the guarded budget to balance both pool assets and add full-range liquidity. There is no owner withdrawal, upgrade, rescue, or negative-liquidity path.

Receiver output50% injection budget50% project treasury

01 · Fee receiver

The accountant and public entry point.

The receiver is configured as the launch fee recipient. It claims actual pair-asset receipts, splits only what arrived, and keeps the liquidity budget separate from the project treasury.

  • claimFeesAndInject() can be called by any wallet.
  • The caller cannot change the split or redirect either balance.
  • A failed injection leaves the recorded budget ready for another attempt.

LiquidityFeeReceiver.sol · public flow

function claimFeesAndInject()
  external nonReentrant
  returns (uint256 claimed, uint128 added)
{
  claimed = _claim();
  if (liquidityBudget < minBatch) return (claimed, 0);

  uint256 batch = liquidityBudget < maxBatch
    ? liquidityBudget
    : maxBatch;
  added = this.executeInjection(batch);
}

LiquidityFeeReceiver.sol · exact split

uint256 treasuryShare =
  (totalClaimed + received) / 2
  - totalClaimed / 2;

treasuryAccrued += treasuryShare;
liquidityBudget += received - treasuryShare;

02 · Permanent vault

Funds can enter. Liquidity cannot leave.

The receiver creates one vault for the verified stock-paired pool. Only that receiver can call inject(). The vault has no owner withdrawal, upgrade, rescue, arbitrary-call, or negative-liquidity path.

Fixed poolChosen once at bindingBounded swapMaximum input and lossPrice guardOracle deviation checkedResiduals stayUnused assets remain locked

LockedLiquidityVault.sol · guarded injection

if (msg.sender != receiver) revert Unauthorized();

(int24 referenceTick, uint256 observedAt) =
  oracle.read(poolId());

checkFresh(observedAt);
checkPrice(poolKey, referenceTick);
swapBoundedQuote();
addPermanentLiquidity();

03 · Oracle and signers

Ten reporters. Six signatures. One accepted state.

Reporter systems observe the reference data and sign the same EIP-712 report offchain. Anyone can relay the finished bundle, but the oracle accepts it only when at least six of the ten approved signer addresses agree.

  • Signer wallets do not hold project funds.
  • Sorted signatures stop duplicate signers from counting twice.
  • Expiry, observation time, and sequence checks prevent stale reports and replay.
  • The vault rejects execution when the reference report is too old.

SignedReferenceOracle.sol · quorum report

report = {
  poolId,
  referenceTick,
  observedAt,
  validUntil,
  sequence
};

require(validSignatures(report) >= 6); // 6 of 10
require(sequence > latestSequence);
accept(report);

04 · Graduation locker

Thirty days—or one irreversible owner call.

Every REDIF token acquired through the full graduation purchase enters the custom locker in one owner-funded deposit. The locker is deployed against the fixed receiver before launch; afterward, parameterless bindToken() reads and permanently records the exact token already accepted by that receiver. The timer starts at the deposit and runs for exactly 30 days. If REDIF crosses $10M during the period, the immutable owner calls eternallyLock() before the deadline. The locker itself does not calculate market capitalization.

No eternal callOwner withdraws after day 30Eternal call madeREDIF remains locked forever

GraduationLocker.sol · irreversible switch

function bindToken() external onlyOwner {
  if (state != State.AwaitingBinding) revert InvalidState();

  address boundToken = receiver.token();
  require(boundToken.code.length != 0);
  require(receiver.vault().code.length != 0);

  token = IERC20(boundToken); // fixed forever
  state = State.AwaitingDeposit;
}

function eternallyLock() external onlyOwner {
  if (state != State.Locked) revert InvalidState();
  if (block.timestamp >= unlockAt) revert LockExpired();

  state = State.EternallyLocked;
}

function withdraw() external onlyOwner nonReentrant {
  if (state != State.Locked) revert InvalidState();
  if (block.timestamp < unlockAt) revert LockActive();

  state = State.Withdrawn;
  REDIF.safeTransfer(owner, REDIF.balanceOf(address(this)));
}
05

One public transaction

What happens when somebody presses inject.

  1. Request sweepThe receiver asks the active launch contract to move pending project fees into escrow. If a sweep is temporarily unavailable, it records the deferral and continues with anything already claimable.sweepFees() / sweepPoolFees()
  2. Claim receiptsThe receiver measures its pair-asset balance before and after the escrow claim. The reported amount must exactly match the tokens that actually arrived.escrow.claimToken()
  3. Record splitCumulative accounting assigns half to the injection budget and half to treasury. Repeated tiny claims cannot distort the ratio through rounding._claim()
  4. Read oracleThe vault loads the latest quorum-approved pool report, rejects stale observations, and compares the live pool tick with the signed reference before execution.oracle.read(poolId)
  5. Balance assetsResidual project tokens are reused first. A capped quote-asset swap then balances both sides while enforcing maximum input, deviation, and loss limits.manager.swap()
  6. Add liquidityThe vault increases its fixed full-range Uniswap v4 position, settles both currencies, checks the price again, and emits the permanent onchain receipt.manager.modifyLiquidity()

Keep reading

Inspect the policy or operate the loop.

Read the whitepaper Inject & Connect