Sherwood Protocol // Documentation

How OutlawFlip Works

A provably fair, instant-settle on-chain coinflip game on Robinhood Chain. Stake in USDG or $OUTLAW, get rewarded in $OUTLAW at 1.9ร— โ€” no waiting, no keeper, no VRF delay.

๐Ÿ”— Network

ChainRobinhood Testnet
Chain ID46630 (0xb626)
RPChttps://rpc.testnet.chain.robinhood.com
Explorerexplorer.testnet.chain.robinhood.com
CurrencyETH

๐Ÿ“œ Contract Addresses

CoinFlipV20x594a1BDf7646A481C13Aaa65cD2561031737577d
OUTLAW Token0xd37Eb14f0E8f76b0e8Dd9c877428dC2e5cd09E50
USDG Token0x9F4E3861B55dcB673c6C8ca94C737d0DA99bE1fa

๐ŸŽฎ How to Play

  1. Connect Wallet โ€” Click "Connect Wallet" and approve MetaMask. The app will auto-add Robinhood Testnet to your wallet if not already configured.
  2. Choose Token โ€” Select USDG or $OUTLAW as your stake. Rewards are always paid in $OUTLAW.
  3. Set Amount โ€” Enter your bet amount. Min: 1,000 OUTLAW. Max: 10,000,000 OUTLAW.
  4. Pick a Side โ€” Choose HEADS (The Hood) or TAILS (The Crown).
  5. Flip โ€” Click "Loose the Arrow". The coin flips and settles instantly in a single transaction.
  6. Win โ€” If you guessed correctly, you receive 1.9ร— your bet in $OUTLAW, sent directly to your wallet in the same transaction.

โšก Instant Settlement

OutlawFlip V2 uses blockhash randomness for instant settlement. Unlike V1 (which used Chainlink VRF and required a separate keeper to fulfill random words), V2 settles the bet in the same transaction as the placeBet call.

1 User calls placeBetWithOutlaw()
โ†’
2 Contract transfers stake in
โ†’
3 Blockhash generates result
โ†’
4 If won: payout sent instantly
โ†’
5 BetSettled event emitted

All in one transaction, one block. No waiting, no keeper, no VRF delay.

๐Ÿ’ฐ Payout Structure

OutcomePayoutNet Profit
Win1.9ร— bet+0.9ร— bet
Lose0โˆ’1.0ร— bet

House Edge: 5% (RTP = 95%)
Multiplier: 19/10 = 1.9ร—
Example: Bet 1,000 OUTLAW on HEADS โ†’ Win โ†’ Receive 1,900 OUTLAW (net +900).

๐Ÿ” Randomness

The result is determined by a hash of:

keccak256(
  blockhash(block.number - 1),
  block.timestamp,
  msg.sender,
  nextBetId,
  tx.gasprice
)

The least significant bit of this hash determines the result (0 = HEADS, 1 = TAILS). This is unpredictable at bet time and cannot be manipulated by the player.

๐Ÿ›ก Security

  • ReentrancyGuard on all bet functions
  • SafeERC20 for all token transfers
  • Solvency check โ€” bet rejected if bankroll < payout
  • Ownable โ€” only owner can withdraw, pause, or set limits
  • Non-custodial โ€” payouts sent directly to player wallet

๐Ÿ“Š Contract Functions

Player

placeBetWithOutlaw(uint256 amount, uint8 choice) โ†’ (uint256 betId, bool won)
placeBetWithUSDG(uint256 usdgAmount, uint8 choice) โ†’ (uint256 betId, bool won)
quoteUsdgToOutlaw(uint256 usdgAmount) โ†’ (uint256 outlawAmount)

Views

availableOutlaw() โ†’ (uint256)
lockedOutlaw() โ†’ (uint256)      // always 0 in V2
minBetOutlaw() โ†’ (uint256)
maxBetOutlaw() โ†’ (uint256)
nextBetId() โ†’ (uint256)
paused() โ†’ (bool)
bets(uint256 betId) โ†’ (Bet)
getRecentBets(uint256 offset, uint256 limit) โ†’ (Bet[])
getPlayerBets(address player, uint256 limit) โ†’ (Bet[])

Admin (owner only)

fundBankroll(uint256 amount)
withdrawOutlaw(address to, uint256 amount)
withdrawUSDG(address to, uint256 amount)
setBetLimits(uint256 min_, uint256 max_)
setPaused(bool paused_)