Experimental NFT standard for permissionless royalty enforcement
ERC721G solves the creator royalty problem by allowing transfers to execute optimistically while introducing economic consequences for unpaid royalties. Instead of blocking trades or whitelisting marketplaces, it uses a locked state that makes unpaid transfers economically undesirable.
════════════════════════════════════════════════════════════════════════════════
ABSTRACT
════════════════════════════════════════════════════════════════════════════════
ERC721G extends ERC-721 with guaranteed on-chain royalty enforcement. Unlike
ERC-2981 which is merely informational, or ERC721C which requires permissioned
marketplace whitelisting, ERC721G makes royalty payment a prerequisite for
token transferability—while remaining fully permissionless.
The standard introduces:
• Deferred payment support (compatible with marketplace payment flows)
• Dynamic floor pricing via GLUE Protocol collateral oracle
• Per-token locking mechanism for unpaid royalties
• transferFrom2: A new transfer primitive with native royalty enforcement
• approve2: ERC-20-style count-based allowances for transferFrom2
════════════════════════════════════════════════════════════════════════════════
- ERC-2981 provides royalty information but no enforcement → marketplaces ignore it
- Whitelist approaches (ERC-721C) enforce royalties but centralize control and fragment liquidity
- Current reality: Creator royalties collapsed from universal to near-zero compliance
ERC721G uses deferred payment reconciliation:
- Transfers execute freely - No blocking, no whitelisting
- Unpaid items lock - Can't create new listings until royalty paid
- Payment unlocks - ETH/WETH sent to contract unlocks items automatically
- Floor price royalties - Based on GLUE Protocol's verifiable backing, not market speculation
- Compounding backing - Royalties flow to GLUE → floor rises → future royalties increase
ERC721G operates under a fundamental constraint: the NFT contract only observes two events - transferFrom() calls (when tokens move) and receive() calls (when ETH arrives). It cannot see marketplace transaction structure, payment timing, or coordination between calls.
This constraint forces a specific solution pattern:
- Transfer executes immediately (standard ERC-721 ownership change)
- Token ID added to locked list
- No payment verification attempted (contract can't know if/when payment arrives)
- Marketplace listing approvals seized for locked tokens
- Result: Buyer owns the NFT, but can't create new listings until unlocked
- Native ETH arrives at contract
- Contract checks both ETH and WETH balances (WETH tracked via balance checks)
- LIFO unlocking: most recently locked tokens unlocked first
- Handles same-transaction payments optimally
- Works regardless of marketplace transaction structure
- Result: Tokens unlock as payment is processed (ETH or WETH)
This execute-then-reconcile pattern works with any marketplace because it makes zero assumptions about transaction structure. Payment can arrive before transfer, after transfer in same transaction, in separate transaction, or never—the protocol handles all cases uniformly.
When payment and transfer happen in the same transaction (most common case), the just-transferred token will be at the end of the locked list. LIFO unlocking processes it first, so the buyer receives an unlocked token even though the contract saw transfer and payment as separate events.
A locked token is fully owned but has degraded liquidity:
What locked tokens CAN do:
- ✅ Be owned and displayed in wallet
- ✅ Be transferred by owner directly (gifts, wallet migrations)
- ✅ Be burned to claim GLUE backing
- ✅ Execute existing marketplace listings (if unlocked before lock occurred)
- ✅ Participate in all non-marketplace functions
What locked tokens CANNOT do:
- ❌ Create new marketplace listings (
getApproved()returnsaddress(0)) - ❌ Be transferred via marketplace
transferFrom(authorization fails on locked items)
This distinction is crucial: existing listings of unlocked items still work. The lock only prevents creating new listings, not executing existing ones. Composability is preserved.
ERC721G uses a two-tier approval system:
External queries (getApproved(tokenId)):
- Returns
address(0)for locked tokens - Marketplaces see "not approved" and block listing creation
- Returns actual approval for unlocked tokens
Internal checks (_getApprovedInternal(tokenId)):
- Used during
transferFromexecution - Returns actual stored approval regardless of lock state
- Allows owner direct transfers to succeed
This split allows the protocol to block new listings while preserving owner rights and existing unlocked listings.
┌───────────────────────────────────────────────────────────────────────────────┐
│ ROYALTY CALCULATION │
├───────────────────────────────────────────────────────────────────────────────┤
│ │
│ Floor Price Derivation: │
│ ────────────────────────────────────────────────────────────────────────── │
│ floorPrice = GLUE.getCollateralByAmount(1, [ETH, WETH]) │
│ = (ETH collateral per NFT) + (WETH collateral per NFT) │
│ = max(calculated, 0.0000001 ETH) // Minimum threshold │
│ │
│ Minimum Royalty: │
│ ────────────────────────────────────────────────────────────────────────── │
│ minRoyalty = floorPrice × totalRoyaltyBps / 10000 │
│ │
│ Example: floorPrice = 0.1 ETH, totalRoyalty = 500 BPS (5%) │
│ minRoyalty = 0.1 ETH × 500 / 10000 = 0.005 ETH │
│ │
└───────────────────────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────────────────┐
│ FEE STRUCTURE │
├───────────────────────────────────────────────────────────────────────────────┤
│ │
│ Distribution Rewards: │
│ ────────────────────────────────────────────────────────────────────────── │
│ • processRoyalties() caller: 0.05% (5 BPS) of distributed amount │
│ • receive() auto-distribution: 0.05% (5 BPS) as unlock budget │
│ │
│ Marketplace Incentive (transferFrom2): │
│ ────────────────────────────────────────────────────────────────────────── │
│ • 1.0% (100 BPS) of royalty payment → msg.sender (marketplace) │
│ • 99.0% → royalty receivers │
│ │
│ BPS Reference: │
│ ────────────────────────────────────────────────────────────────────────── │
│ 10000 BPS = 100% │ 1000 BPS = 10% │ 100 BPS = 1% │ 10 BPS = 0.1% │
│ │
└───────────────────────────────────────────────────────────────────────────────┘
┌───────────────────────────────────────────────────────────────────────────────┐
│ ROYALTY CONFIGURATION │
├───────────────────────────────────────────────────────────────────────────────┤
│ │
│ Receivers: │
│ ────────────────────────────────────────────────────────────────────────── │
│ • Index 0: GLUE (permanent, minimum 1 BPS = 0.01%) │
│ • Index 1-10: Custom receivers (optional) │
│ • Maximum 11 total receivers │
│ │
│ Limits: │
│ ────────────────────────────────────────────────────────────────────────── │
│ • Maximum total royalty: 1000 BPS (10%) │
│ • Minimum GLUE share: 1 BPS (0.01%) │
│ • GLUE cannot be removed (permanent at index 0) │
│ │
└───────────────────────────────────────────────────────────────────────────────┘
- Transfers happen immediately, locking occurs after
- Works with any marketplace transaction structure
- Automatic unlock when payment arrives via
receive() - LIFO optimization for same-transaction payments
- Royalties calculated from verifiable floor price (GLUE backing ÷ supply)
- Portion of royalties automatically sent to GLUE backing
- Creates compounding floor price growth
- Aligns creator revenue with holder value
- Atomic royalty-paid transfers (no locking)
- 1% marketplace reward for using this function
- Allowance-based approval (approve2/batchTransferFrom2)
- Better UX + economic incentive for adoption
- Flash loan protection against backing manipulation
- Re-entrancy guards using transient storage (EIP-1153)
- High-precision math (512-bit intermediate calculations)
- LIFO unlocking for same-transaction payments
- Up to 11 royalty receivers (GLUE + 10 custom)
- Configurable royalty percentages
- Exemption system for specific addresses
- Emergency disable functionality
npm install @glue-finance/expansions-packimport "@glue-finance/expansions-pack/contracts/blueprints/ERC721G.sol";
contract MyNFT is ERC721G {
constructor(
string memory name,
string memory symbol,
string memory contractURI,
address weth,
uint256 glueRoyaltyBps,
address[] memory receivers,
uint256[] memory sharesBps,
bool royaltyActive
) ERC721G(
name,
symbol,
contractURI,
weth,
glueRoyaltyBps,
receivers,
sharesBps,
royaltyActive
) {
// Your initialization
}
function mint(address to, uint256 tokenId) external {
_mint(to, tokenId);
}
}/**
* @param name_ Collection name
* @param symbol_ Collection symbol
* @param contractURI_ ERC-7572 contract metadata URI
* @param weth_ WETH contract address for this network
* @param glueRoyaltyBps_ GLUE's royalty share in BPS (minimum 1 = 0.01%)
* @param receivers_ Additional royalty receivers (excluding GLUE)
* @param sharesBps_ Shares for additional receivers in BPS
* @param royaltyActive_ Whether to enable royalty enforcement initially
*/// 5% total royalty: 1% to GLUE, 4% to artist
uint256 glueRoyaltyBps = 100; // 1% to GLUE (required minimum)
address[] memory receivers = new address[](1);
receivers[0] = artistAddress;
uint256[] memory sharesBps = new uint256[](1);
sharesBps[0] = 400; // 4% to artist
MyNFT nft = new MyNFT(
"My Collection",
"MYNFT",
"ipfs://QmMetadata...",
0x7b79995e5f793A07Bc00c21412e50Ecae098E7f9, // WETH on Sepolia
glueRoyaltyBps,
receivers,
sharesBps,
true // Enable royalty enforcement
);┌───────────────────────────────────────────────────────────────────────────────┐
│ INTERFACE │
├───────────────────────────────────────────────────────────────────────────────┤
│ │
│ CORE FUNCTIONS │
│ ─────────────────────────────────────────────────────────────────────────── │
│ transferFrom2(from, to, tokenId) Royalty-enforced single transfer │
│ batchTransferFrom2(from, to, ids[]) Royalty-enforced batch transfer │
│ approve2(operator, amount) ERC20-style count allowance │
│ allowance2(owner, spender) → uint256 Query approve2 allowance │
│ │
│ ROYALTY FUNCTIONS │
│ ─────────────────────────────────────────────────────────────────────────── │
│ processRoyalties() Distribute accumulated royalties │
│ unlockItems() Pay to unlock caller's locked items │
│ unlockItems(itemIds[]) Pay royalty to unlock specific items │
│ │
│ VIEW FUNCTIONS │
│ ─────────────────────────────────────────────────────────────────────────── │
│ getMinimumRoyalty() → uint256 Minimum royalty per transfer │
│ getImpliedFloorPrice() → uint256 Floor price from GLUE collateral │
│ isItemLocked(id) → bool Check if item is locked │
│ isRoyaltyActive() → bool Check if enforcement is enabled │
│ getRoyaltyOwed(itemIds[]) Check which items locked + cost │
│ │
│ EVENTS │
│ ─────────────────────────────────────────────────────────────────────────── │
│ ItemLocked(itemId) Emitted when item becomes locked │
│ ItemUnlocked(itemId) Emitted when item is unlocked │
│ RoyaltyProcessed(...) Emitted on royalty distribution │
│ Approval2(owner, operator, amount) Emitted on approve2 │
│ │
└───────────────────────────────────────────────────────────────────────────────┘
transferFrom(from, to, tokenId)
│
▼
┌────────────────────────────────────────────────┐
│ EXEMPTION CHECK │
│ Skip enforcement if: │
│ • Minting (from = 0) │
│ • Burning (to = 0/DEAD/GLUE) │
│ • Gift (msg.sender = owner) │
│ • Approved address │
│ • Enforcement disabled │
│ • transferFrom2 in progress │
└────────────────────────────────────────────────┘
│ Not exempt
▼
┌────────────────────────────────────────────────┐
│ LOCK CHECK │
│ If _locked[tokenId] == true → REVERT │
│ Token locked from previous TX, must pay first │
└────────────────────────────────────────────────┘
│ Not locked
▼
┌────────────────────────────────────────────────┐
│ EXECUTE TRANSFER FIRST │
│ super._update() - token ownership changes │
│ (Transfer happens BEFORE locking) │
└────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ ADD TO LOCKED LIST │
│ _locked[tokenId] = true │
│ _lockedIds.push(tokenId) // LIFO priority │
│ Counter assigned to new owner │
└────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ PROCESS ROYALTY SPLIT │
│ Check for accumulated payments (ETH/WETH) │
│ If sufficient: unlock this token (LIFO) │
│ If TX ends without payment: LOCKED │
└────────────────────────────────────────────────┘
transferFrom2{value: royalty}(from, to, tokenId)
│
▼
┌────────────────────────────────────────────────┐
│ CHECK msg.value >= getMinimumRoyalty() │
│ CHECK approve2 allowance sufficient │
│ CONSUME allowance (decrement by 1) │
└────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ SET _royaltyPaidTransferActive = true │
│ Execute _transfer(from, to, tokenId) │
│ SET _royaltyPaidTransferActive = false │
│ Note: If already locked, STAYS locked │
└────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ DISTRIBUTE ROYALTY │
│ Marketplace reward: 1% → msg.sender │
│ Remaining 99% → royalty receivers │
│ Update GLUE collateral snapshot │
└────────────────────────────────────────────────┘
Benefits: Token never locked, marketplace earns 1%, atomic
receive() external payable
│
▼
┌────────────────────────────────────────────────┐
│ 1. UNWRAP WETH │
│ If WETH balance >= THRESHOLD, convert │
└────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ 2. DISTRIBUTE TO RECEIVERS │
│ executorReward = balance × 0.05% │
│ distributable = balance - executorReward │
│ For each receiver: proportional to BPS │
└────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ 3. _getGlueSnapshot() - ALL-IN-ONE │
│ Query: currentCollateral (ETH+WETH per NFT) │
│ Query: currentSupply │
│ FLASH LOAN PROTECTION: │
│ If collateral↓ AND supply unchanged: │
│ → Use old values (freeze snapshot) │
│ Else: Update snapshot with new values │
└────────────────────────────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ 4. UNLOCK ITEMS (LIFO) │
│ available = distributed + excess │
│ numToUnlock = available / minRoyalty │
│ Pop from _lockedIds[] (recent first) │
│ excess = leftover (accumulates) │
└────────────────────────────────────────────────┘
Locked items have their approvals "seized"—they appear as unapproved to marketplaces, preventing listing and sale attempts:
getApproved(tokenId):
├── Token locked? → return address(0) // Appears unapproved
└── Token unlocked? → return actual approved address
isApprovedForAll(owner, operator):
├── Owner has ANY locked item? → return false // Can't list anything
└── No locked items? → return actual approval status
_isAuthorized(owner, spender, tokenId):
├── Token locked + spender is GLUE/whitelisted? → Allow
├── Token locked + spender is owner? → Allow (gift)
├── Token locked + other spender? → Block
└── Token unlocked? → Normal ERC721 rules
Important Notes:
- GLUE is automatically added as first receiver (index 0, cannot be removed)
glueRoyaltyBpsmust be ≥ 1 (0.01%)- Total royalties (GLUE + receivers) cannot exceed 1000 BPS (10%)
- Up to 10 additional receivers beyond GLUE
- GLUE is automatically marked as royalty-exempt
contractURI_follows ERC-7572 for contract-level metadata
What happens:
- Marketplace calls
transferFrom(from, to, tokenId) - Transfer executes, ownership changes
- Token added to locked list
- Marketplace sends ETH to contract (same tx)
receive()fires, processes payment via LIFO- Just-transferred token unlocked first
- Buyer receives unlocked token
Outcome: Seamless. Buyer never sees locked state because LIFO unlocking processes most recent lock first.
What happens:
- Marketplace sends ETH to contract first
receive()fires, but no locked tokens exist yet- ETH accumulates in contract balance
- Marketplace calls
transferFrom(from, to, tokenId) - Transfer executes, token added to locked list
- Transaction ends with locked token and excess balance
- Next payment (any trade) unlocks this token
Outcome: Token temporarily locked. Unlocks on next payment received. Edge case handling for unusual transaction ordering.
What happens:
- User calls
transferFromdirectly or via non-paying marketplace - Transfer executes, ownership changes
- Token added to locked list
- No payment arrives
- Token remains locked
Outcome: Owner has the NFT but cannot create new marketplace listings. Can still transfer directly, burn, or send payment manually to unlock.
What happens:
- Seller approves marketplace via
approve2(marketplace, quantity) - Buyer initiates purchase
- Marketplace calls
transferFrom2{value: royalty}(from, to, tokenId) - Contract verifies payment ≥ minimum royalty
- Transfer executes WITHOUT locking
- Royalties distributed to receivers + GLUE
- Marketplace receives 1% reward
Outcome: Perfect UX. No locking, immediate unlock, marketplace earns reward for better integration.
What happens:
- Token is locked from previous unpaid transfer
- Anyone sends ETH or WETH to contract
receive()fires (for ETH) or balance increases (for WETH)- Contract checks both ETH and WETH balances
- LIFO unlocking processes locked list
- Most recent locks cleared first
- Token unlocks when its position reached
Outcome: Manual unlock succeeds. Payment tracked via balance checks for both ETH and WETH.
What happens:
- Owner calls
transferFromto transfer to friend - Check detects owner is sender
- Transfer executes WITHOUT locking
- No royalty expected for owner transfers
Outcome: Direct transfers bypass enforcement entirely. Owner retains full control.
What happens:
- User transfers to GLUE address or dead address
- Check detects exempt destination
- Transfer executes WITHOUT locking
- No royalty expected for burns
Outcome: Burning/GLUE redemption works normally. No interference with utility.
ERC721G royalties are based on GLUE floor price, not market price:
Floor Price = Total GLUE Backing ÷ NFT Supply
Minimum Royalty = Floor Price × Royalty Percentage
Example:
- Collection: 10,000 NFTs
- GLUE backing: 100 ETH
- Floor price: 0.01 ETH per NFT
- Royalty: 5%
- Minimum royalty per trade: 0.0005 ETH
As trades occur:
- Royalties flow partially to GLUE (1%+)
- GLUE backing increases (100 → 101 ETH)
- Floor price rises (0.01 → 0.0101 ETH)
- Future royalties increase (0.0005 → 0.000505 ETH)
- Compounding continues...
ERC721G maintains a dynamic array of locked token IDs with O(1) operations:
On Lock:
- Token ID pushed to end of
_lockedTokenIdsarray - Position recorded in
_lockedTokenIndexmapping - O(1) operation
On Unlock (LIFO):
- Last token ID popped from array
- Swap-and-pop for non-terminal positions
- Index mapping updated
- O(1) operation regardless of position
This structure enables efficient batch unlocking: when payment arrives, the contract can unlock multiple tokens in a single transaction without iteration limits.
Minted → Unlocked ←→ Locked
↓ ↓ ↓
Burned Burned Burned
Transitions to Locked:
- transferFrom() without payment (marketplace trade)
- transferFrom() with insufficient payment
Transitions to Unlocked:
- receive() processes payment (checks ETH + WETH balances, LIFO unlock)
- transferFrom2() with payment (never locks) - accepts ETH or WETH
- Owner direct transfer (bypass)
- Transfer to exempt address (bypass)
Always Unlocked (exempt):
- Transfers from owner to anyone (direct)
- Transfers to GLUE or dead address (burn)
- Transfers involving exempt addresses
- When royalty enforcement disabled
Token Ownership Functions (No Change):
ownerOf(tokenId)- Returns actual owner regardless of lockbalanceOf(owner)- Counts all tokens regardless of locktokenOfOwnerByIndex(owner, index)- Enumerates all tokenstokenByIndex(index)- Global enumeration works normally
Approval Functions (Lock-Aware):
getApproved(tokenId)- Returnsaddress(0)if locked (blocks listings)isApprovedForAll(owner, operator)- Works normallyapprove(to, tokenId)- Sets approval but ineffective while lockedsetApprovalForAll(operator, approved)- Works normally
Transfer Functions (Lock-Aware):
transferFrom(from, to, tokenId)- Executes but adds to locked list if unpaidsafeTransferFrom(...)- Same as transferFrom with callbacktransferFrom2(from, to, tokenId)- Requires payment, never locks- Direct owner transfers bypass locking entirely
Locked is NOT a custody state. The owner fully controls the token:
Owner can:
- View token in wallet (all standard queries work)
- Transfer to any address directly (bypass enforcement)
- Burn token to claim GLUE backing
- Use in non-marketplace DeFi protocols
- Wait for automatic unlock via payment
Owner cannot:
- Create new marketplace listings (
getApprovedreturns null) - Have marketplace execute
transferFrom(internal auth checks fail on locked)
Existing listings are unaffected:
- If token was unlocked when listed, that listing still works
- Only NEW listings of currently-locked tokens are blocked
This precision is crucial: the lock doesn't break composability or trap users. It creates economic pressure for payment while preserving all ownership rights.
// Batch paid transfers
uint256[] memory tokenIds = new uint256[](3);
tokenIds[0] = 1;
tokenIds[1] = 2;
tokenIds[2] = 3;
nft.batchTransferFrom2{value: totalRoyalties}(
from,
to,
tokenIds
);// Check if token is locked
bool locked = nft.isLocked(tokenId);
// Get all locked token IDs
uint256[] memory lockedIds = nft.getLockedIds();
// Get minimum royalty for a token
uint256 minRoyalty = nft.getMinimumRoyalty(tokenId);
// Get floor price from GLUE
uint256 floorPrice = nft.getFloorPrice();-
Deploy with GLUE integration:
- Get your token's GLUE address from GLUE Protocol
- Configure royalty split (min 1% to GLUE)
- Deploy ERC721G with your parameters
-
Set royalty receivers:
- Add up to 10 custom receivers
- Configure BPS allocation (max 10,000 total)
- Test with small trades first
-
Monitor backing growth:
- Watch GLUE backing accumulate
- Track floor price increases
- Optionally reinvest earnings to GLUE for compounding
Option 1: Standard Integration (No Changes)
- Continue using
transferFrom()as normal - Items lock → users send payment → items unlock
- Works but suboptimal UX
Option 2: transferFrom2 Integration (Recommended)
- Implement
approve2approval flow - Call
transferFrom2{value: royalty}()with payment - Earn 1% marketplace reward
- Better UX (no locking)
Integration steps:
// 1. User approves marketplace
nft.approve2(marketplaceAddress, 1);
// 2. Calculate minimum royalty
uint256 minRoyalty = nft.getMinimumRoyalty(tokenId);
// 3. Execute paid transfer
nft.transferFrom2{value: minRoyalty}(from, to, tokenId);
// 4. Marketplace automatically receives 1% rewardBuying:
- Marketplace handles payment automatically
- If using transferFrom, item locks briefly then unlocks
- If using transferFrom2, no lock occurs
Selling:
- List on any marketplace (no restrictions)
- Royalty based on floor price, not your listing price
- Payment handled automatically
If locked:
- Wait for payment processing (usually same transaction)
- Or send ETH directly to contract to unlock
- Locked items can still be owned/burned normally
ERC721G is optimized for efficiency:
- O(1) lock/unlock operations (swap-and-pop pattern)
- Transient storage for re-entrancy (EIP-1153, saves ~15k gas)
- Batch processing for multiple unlocks
- LIFO unlocking for same-transaction payments
- Efficient approval checks using counter mappings
| Feature | ERC-721 | ERC-2981 | ERC-721C | ERC721G |
|---|---|---|---|---|
| Royalty enforcement | ❌ | ❌ | ✅ | ✅ |
| Permissionless | ✅ | ✅ | ❌ | ✅ |
| Backward compatible | N/A | ✅ | ❌ | ✅ |
| Floor price based | ❌ | ❌ | ❌ | ✅ |
| Marketplace incentives | ❌ | ❌ | ❌ | ✅ |
| Compounding backing | ❌ | ❌ | ❌ | ✅ |
This is an experimental standard. We need:
- 🔍 Security researchers - Find vulnerabilities
- 🏗️ Marketplace builders - Integration feedback
- 🎨 Creators - Real-world usage insights
- 💻 Developers - Code improvements
- 📊 Economists - Mechanism design feedback
How to contribute:
- Open issues for bugs/suggestions
- Submit PRs with improvements
- Share integration experiences
- Propose mechanism alternatives
- White Paper: WHITEPAPER.md
- GLUE Protocol: glue.finance
- Documentation: wiki.glue.finance
- Discord: discord.gg/glue-fi
- Expansions Pack: github.com/glue-finance/expansions
This is experimental software. ERC721G is a first attempt at solving on-chain royalty enforcement. It has not been battle-tested at scale. Use at your own risk. The standard may have edge cases we haven't discovered. We welcome feedback and collaboration to improve it.
The code is provided as-is. While we've taken care to implement security best practices, no guarantee of security or fitness for any particular purpose is made. Independent audit is ongoing but not yet complete.
Built with ❤️ by La-Li-Lu-Le-Lo (@lalilulel0x) and the Glue Finance Team
🚀 Start building: npm install @glue-finance/expansions-pack