WYAM
0x7f3aecc694f298e0010f8a31ec49250506bb3b7c
Verification
Verified
v0.8.24+commit.e11b9ed9
Type
Contract
2,220 bytes
ABI entries
19
7 read · 5 write
License
none
Contract information
- Address
- 0x7f3aecc694f298e0010f8a31ec49250506bb3b7c
- Chain
- Robinhood Chain (4663)
- Compiler
- v0.8.24+commit.e11b9ed9
- Optimization
- Enabled
- Creator
- 0x7355d0EaFe…76b1E925Fd
- Creation tx
- 0xd525dcd98c…cc8ab4a2eb
Token
- Name
- YAM
- Symbol
- YAM
- Decimals
- 18
- Holders
- 243
- Market
- View token page →
Read contract (7)
allowance(address, address) → uint256
balanceOf(address) → uint256
decimals() → uint8
name() → string
symbol() → string
totalSupply() → uint256
yam() → address
Events (4)
ApprovalTransferUnwrapWrap
ABI
[
{
"inputs": [
{
"internalType": "address",
"name": "_yam",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "InsufficientAllowance",
"type": "error"
},
{
"inputs": [],
"name": "InsufficientBalance",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "owner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Approval",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "from",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "to",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "value",
"type": "uint256"
}
],
"name": "Transfer",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "user",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "wyamIn",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "yamOut",
"type": "uint256"
}
],
"name": "Unwrap",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "user",
"type": "address"
},
{
"indexed": false,
"internalType": "uint256",
"name": "yamIn",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "wyamOut",
"type": "uint256"
}
],
"name": "Wrap",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
},
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "allowance",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "spender",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "approve",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"name": "balanceOf",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "name",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "symbol",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "totalSupply",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transfer",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "from",
"type": "address"
},
{
"internalType": "address",
"name": "to",
"type": "address"
},
{
"internalType": "uint256",
"name": "amount",
"type": "uint256"
}
],
"name": "transferFrom",
"outputs": [
{
"internalType": "bool",
"name": "",
"type": "bool"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "wyamAmount",
"type": "uint256"
}
],
"name": "unwrap",
"outputs": [
{
"internalType": "uint256",
"name": "yamAmount",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint256",
"name": "yamAmount",
"type": "uint256"
}
],
"name": "wrap",
"outputs": [
{
"internalType": "uint256",
"name": "wyamAmount",
"type": "uint256"
}
],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "yam",
"outputs": [
{
"internalType": "contract IYAM",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
]Source code
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
/// @notice Minimal ERC20 interface for YAM.
interface IYAM {
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function balanceOf(address account) external view returns (uint256);
function toInternal(uint256 effectiveAmount) external view returns (uint256);
function toEffective(uint256 internalAmount) external view returns (uint256);
function scalingFactor() external view returns (uint256);
function internalBalanceOf(address account) external view returns (uint256);
}
/// @title WYAM — non-rebasing wrapper around YAM
/// @notice Sushi V3 (and most DEX/lending) can't handle rebasing tokens because pool
/// accounting reads balanceOf; a rebase would silently change the pool's YAM balance.
/// WYAM tracks internal (pre-scalingFactor) units. 1 WYAM at deploy = 1 YAM at deploy.
/// As scalingFactor grows, redeeming WYAM returns MORE YAM.
///
/// Wrap: send N YAM → mint N * BASE / scalingFactor WYAM
/// Unwrap: burn N WYAM → send N * scalingFactor / BASE YAM
contract WYAM {
// NOTE: filename is WYAM.sol for repo consistency, but SYMBOL is "YAM".
// This is the static, DEX-facing token — what Sushi pools hold and wallets show.
// YAM.sol (rebasing) has symbol "sYAM". Users buy YAM (this), convert to sYAM for rebase.
string public constant name = "YAM";
string public constant symbol = "YAM";
uint8 public constant decimals = 18;
IYAM public immutable yam;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
event Wrap(address indexed user, uint256 yamIn, uint256 wyamOut);
event Unwrap(address indexed user, uint256 wyamIn, uint256 yamOut);
error InsufficientBalance();
error InsufficientAllowance();
constructor(address _yam) {
yam = IYAM(_yam);
}
/// @notice Wrap YAM into WYAM. Pulls `yamAmount` from caller.
function wrap(uint256 yamAmount) external returns (uint256 wyamAmount) {
// Take YAM from user first, then measure delta in internal units
uint256 before = yam.internalBalanceOf(address(this));
yam.transferFrom(msg.sender, address(this), yamAmount);
uint256 delta = yam.internalBalanceOf(address(this)) - before;
wyamAmount = delta; // 1 WYAM = 1 internal YAM unit
balanceOf[msg.sender] += wyamAmount;
totalSupply += wyamAmount;
emit Transfer(address(0), msg.sender, wyamAmount);
emit Wrap(msg.sender, yamAmount, wyamAmount);
}
/// @notice Unwrap WYAM into YAM. Burns `wyamAmount` from caller.
function unwrap(uint256 wyamAmount) external returns (uint256 yamAmount) {
if (balanceOf[msg.sender] < wyamAmount) revert InsufficientBalance();
unchecked { balanceOf[msg.sender] -= wyamAmount; }
totalSupply -= wyamAmount;
yamAmount = yam.toEffective(wyamAmount);
yam.transfer(msg.sender, yamAmount);
emit Transfer(msg.sender, address(0), wyamAmount);
emit Unwrap(msg.sender, wyamAmount, yamAmount);
}
// ─── ERC20 core ─────────────────────────────────────────────────────
function transfer(address to, uint256 amount) external returns (bool) {
if (balanceOf[msg.sender] < amount) revert InsufficientBalance();
unchecked { balanceOf[msg.sender] -= amount; }
balanceOf[to] += amount;
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(address from, address to, uint256 amount) external returns (bool) {
uint256 current = allowance[from][msg.sender];
if (current < amount) revert InsufficientAllowance();
if (current != type(uint256).max) allowance[from][msg.sender] = current - amount;
if (balanceOf[from] < amount) revert InsufficientBalance();
unchecked { balanceOf[from] -= amount; }
balanceOf[to] += amount;
emit Transfer(from, to, amount);
return true;
}
function approve(address spender, uint256 amount) external returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
}
Chain explorer4313msChain node74ms