Lottery Integration Fix
๐ Issue Foundโ
The ShareOFT contract was calling the CreatorLotteryManager with an incorrect interface.
Before (BROKEN):โ
// โ Wrong interface
interface ICreatorLotteryManager {
function processSwapLottery(address recipient, address token, uint256 amount)
external returns (uint256);
}
// โ Wrong call
ICreatorLotteryManager(mgr).processSwapLottery(recipient, address(this), amount)
After (FIXED):โ
// โ
Correct interface
interface ICreatorLotteryManager {
function processSwapLottery(
address creatorCoin, // The underlying creator token (AKITA)
address trader, // The buyer
address tokenIn, // The token being bought (wsAKITA)
uint256 amountIn // Amount bought
) external payable returns (uint256);
}
// โ
Correct call with creator coin lookup
address creatorCoin = vault != address(0) ? ICreatorOVault(vault).asset() : address(0);
ICreatorLotteryManager(mgr).processSwapLottery(
creatorCoin, // e.g., AKITA token address
recipient, // Buyer address
address(this), // wsAKITA (ShareOFT)
amount // Amount of wsAKITA bought
)
๐ง What Was Fixedโ
1. Updated Interface (CreatorShareOFT.sol)โ
- Changed
ICreatorLotteryManagerinterface to match the actual contract - Added
payablemodifier (lottery may require gas fees for VRF) - Updated parameters to match expected signature
2. Fixed Function Call (_triggerLottery)โ
- Now fetches the
creatorCoinaddress from the vault - Passes correct parameters in correct order
- Validates
creatorCoinis not zero before calling lottery
3. Added Vault Interfaceโ
- Added
asset()function toICreatorOVaultinterface - This allows ShareOFT to lookup the underlying creator token
โ How It Works Nowโ
Buy Flow with Lottery:โ
1. User buys wsAKITA on Uniswap
โ
2. ShareOFT.transfer() detects it's a buy (from SwapOnly address)
โ
3. _processBuy() executes:
- Takes 6.9% fee โ GaugeController
- Transfers remaining tokens to buyer
โ
4. _triggerLottery() executes:
- Looks up AKITA token address from vault
- Calls LotteryManager.processSwapLottery(AKITA, buyer, wsAKITA, amount)
โ
5. LotteryManager:
- Verifies AKITA is registered & active
- Calculates USD value using AKITA oracle
- Creates lottery entry with probability based on trade size
- May trigger instant win via VRF
๐งช Testing Checklistโ
Unit Tests Needed:โ
-
ShareOFT._triggerLottery()calls lottery with correct parameters - Lottery call succeeds when vault is set
- Lottery call fails gracefully when vault is not set
- Lottery call doesn't revert the transfer if it fails
Integration Tests Needed:โ
-
End-to-end buy flow:
- User swaps ETH โ wsAKITA on Uniswap
- Fee is collected
- Lottery entry is created
- Transfer completes successfully
-
Creator coin lookup:
- Verify
vault.asset()returns correct AKITA address - Verify lottery manager receives correct creator coin
- Verify
Manual Testing:โ
# 1. Deploy contracts
forge script script/DeployBase.s.sol --rpc-url base --broadcast
# 2. Buy wsAKITA on testnet DEX
# - Watch for LotteryTriggered event
# - Check lottery manager state
# 3. Verify parameters
cast call $LOTTERY_MANAGER "entries(uint256)" <entryId>
# Should show:
# - creatorCoin = AKITA address (0x5b67...)
# - trader = buyer address
# - tokenIn = wsAKITA address
# - amountIn = amount bought
๐ Key Changes Summaryโ
File: contracts/layerzero/CreatorShareOFT.solโ
| Change | Before | After |
|---|---|---|
| Interface params | (recipient, token, amount) | (creatorCoin, trader, tokenIn, amountIn) |
| Interface modifier | No payable | Added payable |
| Call params | (recipient, this, amount) | (creatorCoin, recipient, this, amount) |
| Creator coin | Not passed | Fetched from vault.asset() |
| Vault interface | No asset() | Added asset() function |
๐ฏ Why This Mattersโ
Before Fix:โ
- โ Lottery calls would fail silently
- โ No lottery entries created for buyers
- โ Jackpot never awarded
- โ Social-fi engagement broken
After Fix:โ
- โ Lottery calls succeed
- โ Buyers get lottery entries
- โ Jackpot awards work correctly
- โ Social-fi engagement enabled
๐ Deployment Stepsโ
-
Recompile contracts:
forge build -
Run tests:
forge test --match-contract ShareOFT -
Deploy to testnet first:
forge script script/DeployBase.s.sol --rpc-url base-sepolia --broadcast --verify -
Verify lottery integration:
- Make test swap
- Check for
LotteryTriggeredevent - Verify entry in lottery manager
-
Deploy to mainnet:
forge script script/DeployBase.s.sol --rpc-url base --broadcast --verify
๐ Expected Events After Fixโ
When a user buys wsAKITA, you should see these events in order:
1. Transfer(from: uniswapPool, to: feeCollector, value: feeAmount)
2. Transfer(from: uniswapPool, to: buyer, value: transferAmount)
3. BuyFee(from: pool, to: buyer, amount: totalAmount, fee: feeAmount)
4. FeeCollected(gauge: gaugeController, amount: feeAmount)
5. LotteryTriggered(recipient: buyer, amount: transferAmount, entryId: X)
If LotteryTriggered is missing, the lottery call failed!
๐ Related Filesโ
contracts/layerzero/CreatorShareOFT.sol- Main fixcontracts/lottery/CreatorLotteryManager.sol- Lottery managercontracts/vault/CreatorOVault.sol- Vault (implementsasset())contracts/governance/CreatorGaugeController.sol- Fee recipient
โ ๏ธ Important Notesโ
-
Backward Compatibility:
- This is a breaking change if contracts are already deployed
- Existing ShareOFT contracts will need to be redeployed or upgraded
-
Upgrade Path:
- If using proxy pattern: Upgrade implementation
- If not upgradeable: Deploy new ShareOFT and migrate liquidity
-
Gas Considerations:
- Lottery call now includes
payablemodifier - May require small ETH amount for cross-chain VRF
- Test gas costs on testnet first
- Lottery call now includes
โ Verification Commandsโ
After deployment, verify the fix:
# Check ShareOFT has correct lottery interface
cast abi-encode "processSwapLottery(address,address,address,uint256)" \
$AKITA_TOKEN $BUYER $WSAKITA_TOKEN 1000000000000000000
# Make a test buy and check events
cast logs --address $WSAKITA_TOKEN --from-block latest
# Verify lottery entry was created
cast call $LOTTERY_MANAGER "entryCounter()"
Status: โ
FIXED
Priority: ๐ด CRITICAL - Required for lottery functionality
Tested: โณ Pending integration tests