$npx -y skills add basezh/agent-skills-on-base --skill yoinkPlay Yoink, an onchain capture-the-flag game on Base. Yoink the flag from the current holder, check game stats and leaderboards, view player scores, and compete for the trophy. Uses Bankr for transaction execution.
| 1 | # Yoink |
| 2 | |
| 3 | Play Yoink, an onchain capture-the-flag game on Base. Yoink the flag from the current holder to start your clock. The player with the most total yoinks holds the trophy. |
| 4 | |
| 5 | **Contract:** `0x4bBFD120d9f352A0BEd7a014bd67913a2007a878` on Base (chain ID 8453) |
| 6 | |
| 7 | ## Game Rules |
| 8 | |
| 9 | 1. **Yoink the flag** - Call `yoink()` to take the flag from the current holder |
| 10 | 2. **Cooldown** - You must wait 10 minutes (600 seconds) between yoinks |
| 11 | 3. **No self-yoink** - You cannot yoink from yourself |
| 12 | 4. **Accumulate time** - While you hold the flag, your time score increases |
| 13 | 5. **Compete for trophy** - The player with the most total yoinks holds the trophy (token ID 2) |
| 14 | 6. **Track yoinks** - Your total yoink count is tracked separately from time |
| 15 | |
| 16 | ## Contract Interface |
| 17 | |
| 18 | **RPC template:** |
| 19 | ```bash |
| 20 | curl -s -X POST https://mainnet.base.org -H "Content-Type: application/json" \ |
| 21 | -d '{"jsonrpc":"2.0","method":"eth_call","params":[{"to":"0x4bBFD120d9f352A0BEd7a014bd67913a2007a878","data":"SELECTOR+PARAMS"},"latest"],"id":1}' | jq -r '.result' |
| 22 | ``` |
| 23 | |
| 24 | | Function | Selector | Params | Returns | |
| 25 | |----------|----------|--------|---------| |
| 26 | | `yoink()` | `0x9846cd9e` | - | (write) | |
| 27 | | `lastYoinkedBy()` | `0xd4dbf9f4` | - | address | |
| 28 | | `lastYoinkedAt()` | `0x6a99616f` | - | uint256 timestamp | |
| 29 | | `totalYoinks()` | `0xa5d0dadd` | - | uint256 | |
| 30 | | `topYoinker()` | `0x6a974e6e` | - | address (trophy holder) | |
| 31 | | `mostYoinks()` | `0xd2d7774a` | - | uint256 (record) | |
| 32 | | `COOLDOWN()` | `0xa2724a4d` | - | uint256 (600) | |
| 33 | | `score(address)` | `0x776f3843` | addr (32B padded) | (yoinks, time, lastYoinkedAt) | |
| 34 | | `balanceOf(address,uint256)` | `0x00fdd58e` | addr + tokenId | uint256 (FLAG_ID=1, TROPHY_ID=2) | |
| 35 | |
| 36 | **Encoding:** Addresses are zero-padded to 32 bytes. `score()` returns 96 bytes (3 × uint256). |
| 37 | |
| 38 | ## Yoinking |
| 39 | |
| 40 | Use Bankr's arbitrary transaction feature: |
| 41 | |
| 42 | ``` |
| 43 | { |
| 44 | "to": "0x4bBFD120d9f352A0BEd7a014bd67913a2007a878", |
| 45 | "data": "0x9846cd9e", |
| 46 | "value": "0", |
| 47 | "chainId": 8453 |
| 48 | } |
| 49 | ``` |
| 50 | |
| 51 | ## Errors |
| 52 | |
| 53 | | Error | Selector | Meaning | |
| 54 | |-------|----------|---------| |
| 55 | | `SlowDown(uint256)` | `0x58d6f4c6` | Cooldown not elapsed. Param = seconds remaining. | |
| 56 | | `Unauthorized()` | `0x82b42900` | You already hold the flag. | |
| 57 | |
| 58 | **Cooldown check:** `current_time - lastYoinkedAt() >= 600` |
| 59 | |
| 60 | ## Workflow |
| 61 | |
| 62 | - Query `lastYoinkedBy()` and `lastYoinkedAt()` to check status/cooldown |
| 63 | - Ensure cooldown elapsed (600s) and you're not current holder |
| 64 | - Submit yoink transaction via Bankr |
| 65 | - Verify with `lastYoinkedBy()` or `score(address)` |
| 66 | |
| 67 | ## Resources |
| 68 | |
| 69 | - **Basescan:** https://basescan.org/address/0x4bBFD120d9f352A0BEd7a014bd67913a2007a878 (ABI, events, source) |
| 70 | - **Source Code:** https://github.com/horsefacts/yoink-contracts |