@dev.sail.money/sailor 0.1.0-local → 1.0.0-39
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +139 -140
- package/LICENSE +21 -21
- package/README.md +428 -430
- package/docs/PERMISSION_MODEL.md +93 -93
- package/examples/permissions/BoundedApproveAndCallBatch.sol +179 -179
- package/examples/permissions/BoundedBet_Limitless_Base.sol +97 -97
- package/examples/permissions/BoundedBorrow_AaveV3_Arbitrum.sol +94 -94
- package/examples/permissions/BoundedPerp_GMXv2_Arbitrum.sol +154 -154
- package/examples/permissions/BoundedStake_Venice_Base.sol +85 -85
- package/examples/permissions/BoundedSupply_AaveV3_Arbitrum.sol +82 -82
- package/examples/permissions/BoundedSwap_UniswapV3_Base.sol +116 -116
- package/examples/permissions/BoundedSwap_UniswapV4_Unichain.sol +150 -150
- package/examples/permissions/BoundedTransfer_ERC20_Ethereum.sol +73 -73
- package/examples/permissions/BoundedVault_ERC4626_Base.sol +97 -97
- package/examples/permissions/README.md +79 -79
- package/examples/permissions/SailCalldata.sol +118 -118
- package/examples/permissions/foundry.toml +10 -10
- package/examples/permissions/interfaces/IBatchPermission.sol +38 -38
- package/examples/permissions/interfaces/IPermission.sol +18 -18
- package/package.json +44 -45
- package/packages/cli/README.md +34 -34
- package/packages/cli/dist/index.cjs +734 -705
- package/packages/cli/dist/server.cjs +627 -538
- package/packages/sdk/README.md +65 -65
- package/packages/sdk/dist/intelligence.d.ts +1 -1
- package/packages/sdk/dist/intelligence.js +1 -1
- package/packages/sdk/package.json +80 -80
- package/packages/ui/dist/assets/{add-BxpXfVWe.js → add-Gzf62xlX.js} +1 -1
- package/packages/ui/dist/assets/{all-wallets-BKTn_sWK.js → all-wallets-O-pI4o8v.js} +1 -1
- package/packages/ui/dist/assets/{app-store-CfuKbwxR.js → app-store-CeSLaOaQ.js} +1 -1
- package/packages/ui/dist/assets/{apple-BKSBbNYg.js → apple-FGNyQM-D.js} +1 -1
- package/packages/ui/dist/assets/{arrow-bottom-D4bG6gZi.js → arrow-bottom-C1fusORF.js} +1 -1
- package/packages/ui/dist/assets/{arrow-bottom-circle-BNTs1p0T.js → arrow-bottom-circle-AvK1VEpN.js} +1 -1
- package/packages/ui/dist/assets/{arrow-left-2uee3vYv.js → arrow-left-Bu-hq4Ep.js} +1 -1
- package/packages/ui/dist/assets/{arrow-right-BktjMV6h.js → arrow-right-XbZESmct.js} +1 -1
- package/packages/ui/dist/assets/{arrow-top-Izu28fX4.js → arrow-top-DvkVHbhX.js} +1 -1
- package/packages/ui/dist/assets/{bank-USBaAyFM.js → bank-DTThWRvC.js} +1 -1
- package/packages/ui/dist/assets/{basic-C_9KjTEH.js → basic-B9AMgqFE.js} +1 -1
- package/packages/ui/dist/assets/{browser-DAEMAKV7.js → browser-Bhnivm4i.js} +1 -1
- package/packages/ui/dist/assets/{card-DT8yDkKN.js → card-DjIlyU55.js} +1 -1
- package/packages/ui/dist/assets/{ccip-CkqfGSxX.js → ccip-DPAiKntc.js} +1 -1
- package/packages/ui/dist/assets/{checkmark-CsgdEXFj.js → checkmark-DSVYfoVl.js} +1 -1
- package/packages/ui/dist/assets/{checkmark-bold-D2gjOQo2.js → checkmark-bold-BFkw_Q5g.js} +1 -1
- package/packages/ui/dist/assets/{chevron-bottom-tprFynYV.js → chevron-bottom-CyCgyOwY.js} +1 -1
- package/packages/ui/dist/assets/{chevron-left-D2Zj1gNB.js → chevron-left-DTuO2WLr.js} +1 -1
- package/packages/ui/dist/assets/{chevron-right-D1rRuAVe.js → chevron-right-DwB5FZj8.js} +1 -1
- package/packages/ui/dist/assets/{chevron-top-24dL1mbL.js → chevron-top-DKukdWvg.js} +1 -1
- package/packages/ui/dist/assets/{chrome-store-Vy-5niYX.js → chrome-store-Csz4L9Ls.js} +1 -1
- package/packages/ui/dist/assets/{clock-qBjLnVdJ.js → clock-Bg6488Gw.js} +1 -1
- package/packages/ui/dist/assets/{close-DARDwgcu.js → close-BxAJGBxP.js} +1 -1
- package/packages/ui/dist/assets/{coinPlaceholder-BvpIbPlD.js → coinPlaceholder-CCJVgW9w.js} +1 -1
- package/packages/ui/dist/assets/{compass-BMTO0ayt.js → compass-CSQSZaqJ.js} +1 -1
- package/packages/ui/dist/assets/{copy-PaXeRHza.js → copy-CqlzXVB-.js} +1 -1
- package/packages/ui/dist/assets/{core-BFnStQd-.js → core-ClvdTrpG.js} +3 -3
- package/packages/ui/dist/assets/cursor-CKKwWhGQ.js +3 -0
- package/packages/ui/dist/assets/{cursor-transparent-BEMdi-8q.js → cursor-transparent-C1VOGz11.js} +1 -1
- package/packages/ui/dist/assets/{desktop-CfuLLThw.js → desktop-QiLednKV.js} +1 -1
- package/packages/ui/dist/assets/{disconnect-DhwgJMiR.js → disconnect-Bx2TgkML.js} +1 -1
- package/packages/ui/dist/assets/{discord-po8qoN1s.js → discord-6MWX5Rbb.js} +1 -1
- package/packages/ui/dist/assets/{etherscan-BEsz0_yx.js → etherscan-CodIrmJK.js} +1 -1
- package/packages/ui/dist/assets/{events-Bz33Unzu.js → events-DOEm-LTy.js} +1 -1
- package/packages/ui/dist/assets/{exclamation-triangle-7CjTAGOQ.js → exclamation-triangle-Dwr5oCsh.js} +1 -1
- package/packages/ui/dist/assets/{extension-CmxjEWEt.js → extension-C-SoZx1s.js} +1 -1
- package/packages/ui/dist/assets/{external-link-CmQ--bNS.js → external-link-BiDYH90C.js} +1 -1
- package/packages/ui/dist/assets/{facebook-CIBn9b65.js → facebook-Bm27AlfS.js} +1 -1
- package/packages/ui/dist/assets/{fallback-DATyrQlb.js → fallback-Bwpmpy13.js} +1 -1
- package/packages/ui/dist/assets/{farcaster-OJ3Jasxg.js → farcaster-CSW-SjzS.js} +1 -1
- package/packages/ui/dist/assets/{filters-D4x09zeL.js → filters-j3dR7AJK.js} +1 -1
- package/packages/ui/dist/assets/{github-ZlIuMArp.js → github-CQMTSSgW.js} +1 -1
- package/packages/ui/dist/assets/{google-Gwg85sfv.js → google-BBIVBfAd.js} +1 -1
- package/packages/ui/dist/assets/{help-circle-D1uOWYcX.js → help-circle-CEvTLelF.js} +1 -1
- package/packages/ui/dist/assets/{id-C0-5UdYk.js → id-CYRVgSgN.js} +1 -1
- package/packages/ui/dist/assets/{image-D_DUsv8-.js → image-Cm9Ep5G0.js} +1 -1
- package/packages/ui/dist/assets/{index-DdbJhIdl.js → index-4wdo7Ga_.js} +3 -3
- package/packages/ui/dist/assets/{index-CrYzBWfD.js → index-BrP8m1ZI.js} +1 -1
- package/packages/ui/dist/assets/index-C2PQCECq.css +1 -0
- package/packages/ui/dist/assets/{index-DiojfeVM.js → index-DZ07nuwB.js} +1 -1
- package/packages/ui/dist/assets/{index-BCzex_R6.js → index-De_P6mNS.js} +1 -1
- package/packages/ui/dist/assets/index-DrQ9A8dp.js +1775 -0
- package/packages/ui/dist/assets/{index-izd7vu_r.js → index-Z55BVE94.js} +1 -1
- package/packages/ui/dist/assets/{index.es-DdkHhQAj.js → index.es-DnT9Uzwt.js} +4 -4
- package/packages/ui/dist/assets/{info-CiRd_kEG.js → info-DdYqiFMu.js} +1 -1
- package/packages/ui/dist/assets/{info-circle-ypxjqarK.js → info-circle-DkD9oY-S.js} +1 -1
- package/packages/ui/dist/assets/{lightbulb-B-pxLxd8.js → lightbulb-7Q3AhpSP.js} +1 -1
- package/packages/ui/dist/assets/{mail-BYmicuVZ.js → mail-CPagdnfp.js} +1 -1
- package/packages/ui/dist/assets/{metamask-sdk-Ccl6DG7Q.js → metamask-sdk-CQ4tzR6A.js} +1 -1
- package/packages/ui/dist/assets/{mobile-CtP5PqVT.js → mobile-01GVSpey.js} +1 -1
- package/packages/ui/dist/assets/{more-6C2733we.js → more-BPXPYrvy.js} +1 -1
- package/packages/ui/dist/assets/{network-placeholder-CdhxMzqd.js → network-placeholder-CII8WrTF.js} +1 -1
- package/packages/ui/dist/assets/{nftPlaceholder-DVmTWEAY.js → nftPlaceholder-DG5rjRzx.js} +1 -1
- package/packages/ui/dist/assets/{off-DNYLughs.js → off-eemo7R2q.js} +1 -1
- package/packages/ui/dist/assets/{parseSignature-Dq2B5Bu3.js → parseSignature-CaRSntRi.js} +1 -1
- package/packages/ui/dist/assets/{play-store-D7Qut5ta.js → play-store-SIqMwLur.js} +1 -1
- package/packages/ui/dist/assets/{plus-kqMyjt3q.js → plus-DemTM2Nx.js} +1 -1
- package/packages/ui/dist/assets/{qr-code-DiUCWRbz.js → qr-code-BjolKhQv.js} +1 -1
- package/packages/ui/dist/assets/{recycle-horizontal-Boe3XiS-.js → recycle-horizontal-BluxSqWj.js} +1 -1
- package/packages/ui/dist/assets/{refresh-CrBgBQYO.js → refresh-Cto5auO0.js} +1 -1
- package/packages/ui/dist/assets/{reown-logo-CFZCCHSx.js → reown-logo-lrWmaeNj.js} +1 -1
- package/packages/ui/dist/assets/{search-ChTDrghU.js → search-SNmrxLL7.js} +1 -1
- package/packages/ui/dist/assets/{secp256k1-DAV5Q_FR.js → secp256k1-SI0Bxirn.js} +1 -1
- package/packages/ui/dist/assets/{send-DLFbBFe1.js → send-Do8kdKTu.js} +1 -1
- package/packages/ui/dist/assets/{swapHorizontal-BEs3emfG.js → swapHorizontal-HBP1koQV.js} +1 -1
- package/packages/ui/dist/assets/{swapHorizontalBold-CC-Hfa7W.js → swapHorizontalBold-B9g1LqXn.js} +1 -1
- package/packages/ui/dist/assets/{swapHorizontalMedium-BmR0H8DC.js → swapHorizontalMedium-C8JebI_2.js} +1 -1
- package/packages/ui/dist/assets/{swapHorizontalRoundedBold-BdP5NGIH.js → swapHorizontalRoundedBold-37eEYoAp.js} +1 -1
- package/packages/ui/dist/assets/{swapVertical-CPrGEJPY.js → swapVertical-DmacpIGs.js} +1 -1
- package/packages/ui/dist/assets/{telegram-CxNoZ80Q.js → telegram-Dq_CUch4.js} +1 -1
- package/packages/ui/dist/assets/{three-dots-BRa6SBpL.js → three-dots-DbkqGUCU.js} +1 -1
- package/packages/ui/dist/assets/{twitch-BC338bG5.js → twitch-iG0Ncwwy.js} +1 -1
- package/packages/ui/dist/assets/{twitterIcon-BGZmt2i9.js → twitterIcon-CNbKQx87.js} +1 -1
- package/packages/ui/dist/assets/{verify-CEstW0zw.js → verify-BfXT7L3L.js} +1 -1
- package/packages/ui/dist/assets/{verify-filled-OkZb0weU.js → verify-filled-BxqxA6xc.js} +1 -1
- package/packages/ui/dist/assets/{w3m-modal-pS09ECwE.js → w3m-modal-DeDYqwYJ.js} +1 -1
- package/packages/ui/dist/assets/{wallet-BXVKCgC9.js → wallet-BXsUR9Tj.js} +1 -1
- package/packages/ui/dist/assets/{wallet-placeholder-C_kNhB1c.js → wallet-placeholder-bbWbfkZu.js} +1 -1
- package/packages/ui/dist/assets/{walletconnect-CRKIuUHH.js → walletconnect-WsTWE17z.js} +1 -1
- package/packages/ui/dist/assets/{warning-circle-DB2NnwlJ.js → warning-circle-cNSUigh6.js} +1 -1
- package/packages/ui/dist/assets/{x-DT4RmwL5.js → x-gNtNGE0N.js} +1 -1
- package/packages/ui/dist/index.html +14 -14
- package/scripts/check-docs.mjs +262 -262
- package/scripts/check-init.mjs +108 -108
- package/templates/custom-mandate/.sail/contracts/interfaces/IPermission.sol +18 -18
- package/templates/custom-mandate/README.md +116 -116
- package/templates/custom-mandate/foundry.toml +8 -8
- package/templates/custom-mandate/mandates/BoundedCallPermission.sol +41 -41
- package/templates/custom-mandate/mandates/README.md +16 -16
- package/templates/custom-mandate/mandates/SailCalldata.sol +118 -118
- package/templates/default/.cursor/rules +25 -25
- package/templates/default/.env.example +20 -20
- package/templates/default/.github/workflows/agent-tick.yml +33 -33
- package/templates/default/.sail/README.md +13 -13
- package/templates/default/.sail/config.json +10 -10
- package/templates/default/AGENTS.md +171 -171
- package/templates/default/CLAUDE.md +2 -2
- package/templates/default/README.md +16 -16
- package/templates/default/_gitignore +13 -13
- package/templates/default/docs/PERMISSION_MODEL.md +93 -93
- package/templates/default/examples/dca/README.md +16 -16
- package/templates/default/examples/dca/agent.ts +174 -174
- package/templates/default/examples/dca/mandate.ts +45 -45
- package/templates/default/package.json +17 -17
- package/templates/default/src/agent.ts +37 -37
- package/templates/default/src/config.ts +24 -24
- package/templates/default/src/mandate.ts +22 -22
- package/templates/default/tsconfig.json +17 -17
- package/templates/default/ui/README.md +3 -3
- package/templates/lifi-permissions/LifiBoundedApprovePermissionCloneable.sol +84 -84
- package/templates/lifi-permissions/LifiDiamondSwapPermissionCloneable.sol +97 -97
- package/templates/lifi-permissions/README.md +53 -53
- package/packages/ui/dist/assets/cursor-BDvw-B17.js +0 -3
- package/packages/ui/dist/assets/index-BUhrHLpY.js +0 -1775
- package/packages/ui/dist/assets/index-Cq02kQmy.css +0 -1
- package/scripts/postinstall.js +0 -81
|
@@ -1,97 +1,97 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.26;
|
|
3
|
-
|
|
4
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
-
// Protocol : Limitless
|
|
6
|
-
// Version : CTF-based prediction market (on-chain settlement on Base)
|
|
7
|
-
// NOT Polymarket (Polymarket's CLOB matches orders off-chain on Polygon —
|
|
8
|
-
// a permission cannot bound the orders your agent signs off-chain.
|
|
9
|
-
// Limitless settles bets on-chain on Base, so the kernel sees every action.)
|
|
10
|
-
// Chain : Base mainnet
|
|
11
|
-
//
|
|
12
|
-
// ⚠ WARNING — ABI UNVERIFIED ⚠
|
|
13
|
-
// The Limitless exchange contract address and bet-placement function signature
|
|
14
|
-
// below are based on published CTF exchange patterns and public documentation.
|
|
15
|
-
// They have NOT been independently verified against the deployed contracts.
|
|
16
|
-
// YOU MUST verify these before deploying with real funds:
|
|
17
|
-
// 1. Find the Limitless exchange contract address on Basescan.
|
|
18
|
-
// 2. Read its verified ABI and confirm the buy/place function signature.
|
|
19
|
-
// 3. Recompute the selector and update SEL_BUY.
|
|
20
|
-
// 4. Confirm the parameter layout matches BetParams below.
|
|
21
|
-
// Deploying this contract with an unverified ABI may silently PASS or FAIL
|
|
22
|
-
// all dispatches depending on whether the selector matches.
|
|
23
|
-
//
|
|
24
|
-
// ENFORCES ON-CHAIN (kernel calls evaluate() on every dispatch; false ⇒ dispatch blocked)
|
|
25
|
-
// — ASSUMING the unverified ABI above is correct:
|
|
26
|
-
// buy(bytes32 conditionId,uint256 amount,uint256 outcomeIndex) selector = keccak256(sig)[0:4]
|
|
27
|
-
// • target must be LIMITLESS_EXCHANGE
|
|
28
|
-
// • conditionId must be in ALLOWED_CONDITIONS
|
|
29
|
-
// • amount ≤ MAX_STAKE
|
|
30
|
-
// • outcomeIndex must be in ALLOWED_OUTCOMES
|
|
31
|
-
//
|
|
32
|
-
// AGENT-ENFORCED / NOT BOUNDED HERE (off-chain — can change without redeploying this contract):
|
|
33
|
-
// • Market price / odds (on-chain prediction market prices fluctuate)
|
|
34
|
-
// • Timing / frequency of bets
|
|
35
|
-
//
|
|
36
|
-
// VERIFY BEFORE USE:
|
|
37
|
-
// • Confirm Limitless exchange address on Base (Basescan).
|
|
38
|
-
// • Confirm buy function signature and compute selector:
|
|
39
|
-
// keccak256("buy(bytes32,uint256,uint256)")[0:4] == 0x??? — verify on-chain.
|
|
40
|
-
// • Confirm conditionId encoding matches the deployed market IDs.
|
|
41
|
-
// • Update this contract if the ABI or parameter order differs.
|
|
42
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
43
|
-
|
|
44
|
-
import {IPermission, Context} from "@sail/interfaces/IPermission.sol";
|
|
45
|
-
|
|
46
|
-
contract BoundedBet_Limitless_Base is IPermission {
|
|
47
|
-
bytes32 private constant DISCRIMINATOR = keccak256("BoundedBet_Limitless_Base");
|
|
48
|
-
|
|
49
|
-
/// @dev ⚠ UNVERIFIED — replace with verified Limitless exchange address on Base.
|
|
50
|
-
address public immutable LIMITLESS_EXCHANGE;
|
|
51
|
-
mapping(bytes32 => bool) public isAllowedCondition;
|
|
52
|
-
uint256 public immutable MAX_STAKE;
|
|
53
|
-
mapping(uint256 => bool) public isAllowedOutcome;
|
|
54
|
-
|
|
55
|
-
/// @dev ⚠ UNVERIFIED selector. Compute keccak256("buy(bytes32,uint256,uint256)")[0:4]
|
|
56
|
-
/// and confirm it matches the deployed Limitless exchange contract before use.
|
|
57
|
-
bytes4 private constant SEL_BUY = bytes4(keccak256("buy(bytes32,uint256,uint256)"));
|
|
58
|
-
|
|
59
|
-
/// @param limitlessExchange ⚠ VERIFY — Limitless CTF exchange address on Base
|
|
60
|
-
/// @param allowedConditions conditionIds (bytes32) of markets the agent may bet on
|
|
61
|
-
/// @param maxStake Per-bet stake cap in collateral base units
|
|
62
|
-
/// @param allowedOutcomes Outcome indices the agent may select (e.g. [0] for YES only)
|
|
63
|
-
constructor(
|
|
64
|
-
address limitlessExchange,
|
|
65
|
-
bytes32[] memory allowedConditions,
|
|
66
|
-
uint256 maxStake,
|
|
67
|
-
uint256[] memory allowedOutcomes
|
|
68
|
-
) {
|
|
69
|
-
LIMITLESS_EXCHANGE = limitlessExchange;
|
|
70
|
-
MAX_STAKE = maxStake;
|
|
71
|
-
for (uint256 i = 0; i < allowedConditions.length; i++) {
|
|
72
|
-
isAllowedCondition[allowedConditions[i]] = true;
|
|
73
|
-
}
|
|
74
|
-
for (uint256 i = 0; i < allowedOutcomes.length; i++) {
|
|
75
|
-
isAllowedOutcome[allowedOutcomes[i]] = true;
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
function evaluate(bytes calldata txData, Context calldata ctx) external view returns (bool) {
|
|
80
|
-
if (ctx.target != LIMITLESS_EXCHANGE) return false;
|
|
81
|
-
if (ctx.selector != SEL_BUY) return false;
|
|
82
|
-
if (txData.length < 4 + 3 * 32) return false;
|
|
83
|
-
|
|
84
|
-
// ⚠ Assumes: buy(bytes32 conditionId, uint256 amount, uint256 outcomeIndex)
|
|
85
|
-
// Verify parameter order against deployed contract ABI before use.
|
|
86
|
-
(bytes32 conditionId, uint256 amount, uint256 outcomeIndex) =
|
|
87
|
-
abi.decode(txData[4:], (bytes32, uint256, uint256));
|
|
88
|
-
|
|
89
|
-
if (!isAllowedCondition[conditionId]) return false;
|
|
90
|
-
if (amount > MAX_STAKE) return false;
|
|
91
|
-
if (!isAllowedOutcome[outcomeIndex]) return false;
|
|
92
|
-
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
function discriminator() external pure returns (bytes32) { return DISCRIMINATOR; }
|
|
97
|
-
}
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.26;
|
|
3
|
+
|
|
4
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
+
// Protocol : Limitless
|
|
6
|
+
// Version : CTF-based prediction market (on-chain settlement on Base)
|
|
7
|
+
// NOT Polymarket (Polymarket's CLOB matches orders off-chain on Polygon —
|
|
8
|
+
// a permission cannot bound the orders your agent signs off-chain.
|
|
9
|
+
// Limitless settles bets on-chain on Base, so the kernel sees every action.)
|
|
10
|
+
// Chain : Base mainnet
|
|
11
|
+
//
|
|
12
|
+
// ⚠ WARNING — ABI UNVERIFIED ⚠
|
|
13
|
+
// The Limitless exchange contract address and bet-placement function signature
|
|
14
|
+
// below are based on published CTF exchange patterns and public documentation.
|
|
15
|
+
// They have NOT been independently verified against the deployed contracts.
|
|
16
|
+
// YOU MUST verify these before deploying with real funds:
|
|
17
|
+
// 1. Find the Limitless exchange contract address on Basescan.
|
|
18
|
+
// 2. Read its verified ABI and confirm the buy/place function signature.
|
|
19
|
+
// 3. Recompute the selector and update SEL_BUY.
|
|
20
|
+
// 4. Confirm the parameter layout matches BetParams below.
|
|
21
|
+
// Deploying this contract with an unverified ABI may silently PASS or FAIL
|
|
22
|
+
// all dispatches depending on whether the selector matches.
|
|
23
|
+
//
|
|
24
|
+
// ENFORCES ON-CHAIN (kernel calls evaluate() on every dispatch; false ⇒ dispatch blocked)
|
|
25
|
+
// — ASSUMING the unverified ABI above is correct:
|
|
26
|
+
// buy(bytes32 conditionId,uint256 amount,uint256 outcomeIndex) selector = keccak256(sig)[0:4]
|
|
27
|
+
// • target must be LIMITLESS_EXCHANGE
|
|
28
|
+
// • conditionId must be in ALLOWED_CONDITIONS
|
|
29
|
+
// • amount ≤ MAX_STAKE
|
|
30
|
+
// • outcomeIndex must be in ALLOWED_OUTCOMES
|
|
31
|
+
//
|
|
32
|
+
// AGENT-ENFORCED / NOT BOUNDED HERE (off-chain — can change without redeploying this contract):
|
|
33
|
+
// • Market price / odds (on-chain prediction market prices fluctuate)
|
|
34
|
+
// • Timing / frequency of bets
|
|
35
|
+
//
|
|
36
|
+
// VERIFY BEFORE USE:
|
|
37
|
+
// • Confirm Limitless exchange address on Base (Basescan).
|
|
38
|
+
// • Confirm buy function signature and compute selector:
|
|
39
|
+
// keccak256("buy(bytes32,uint256,uint256)")[0:4] == 0x??? — verify on-chain.
|
|
40
|
+
// • Confirm conditionId encoding matches the deployed market IDs.
|
|
41
|
+
// • Update this contract if the ABI or parameter order differs.
|
|
42
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
43
|
+
|
|
44
|
+
import {IPermission, Context} from "@sail/interfaces/IPermission.sol";
|
|
45
|
+
|
|
46
|
+
contract BoundedBet_Limitless_Base is IPermission {
|
|
47
|
+
bytes32 private constant DISCRIMINATOR = keccak256("BoundedBet_Limitless_Base");
|
|
48
|
+
|
|
49
|
+
/// @dev ⚠ UNVERIFIED — replace with verified Limitless exchange address on Base.
|
|
50
|
+
address public immutable LIMITLESS_EXCHANGE;
|
|
51
|
+
mapping(bytes32 => bool) public isAllowedCondition;
|
|
52
|
+
uint256 public immutable MAX_STAKE;
|
|
53
|
+
mapping(uint256 => bool) public isAllowedOutcome;
|
|
54
|
+
|
|
55
|
+
/// @dev ⚠ UNVERIFIED selector. Compute keccak256("buy(bytes32,uint256,uint256)")[0:4]
|
|
56
|
+
/// and confirm it matches the deployed Limitless exchange contract before use.
|
|
57
|
+
bytes4 private constant SEL_BUY = bytes4(keccak256("buy(bytes32,uint256,uint256)"));
|
|
58
|
+
|
|
59
|
+
/// @param limitlessExchange ⚠ VERIFY — Limitless CTF exchange address on Base
|
|
60
|
+
/// @param allowedConditions conditionIds (bytes32) of markets the agent may bet on
|
|
61
|
+
/// @param maxStake Per-bet stake cap in collateral base units
|
|
62
|
+
/// @param allowedOutcomes Outcome indices the agent may select (e.g. [0] for YES only)
|
|
63
|
+
constructor(
|
|
64
|
+
address limitlessExchange,
|
|
65
|
+
bytes32[] memory allowedConditions,
|
|
66
|
+
uint256 maxStake,
|
|
67
|
+
uint256[] memory allowedOutcomes
|
|
68
|
+
) {
|
|
69
|
+
LIMITLESS_EXCHANGE = limitlessExchange;
|
|
70
|
+
MAX_STAKE = maxStake;
|
|
71
|
+
for (uint256 i = 0; i < allowedConditions.length; i++) {
|
|
72
|
+
isAllowedCondition[allowedConditions[i]] = true;
|
|
73
|
+
}
|
|
74
|
+
for (uint256 i = 0; i < allowedOutcomes.length; i++) {
|
|
75
|
+
isAllowedOutcome[allowedOutcomes[i]] = true;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function evaluate(bytes calldata txData, Context calldata ctx) external view returns (bool) {
|
|
80
|
+
if (ctx.target != LIMITLESS_EXCHANGE) return false;
|
|
81
|
+
if (ctx.selector != SEL_BUY) return false;
|
|
82
|
+
if (txData.length < 4 + 3 * 32) return false;
|
|
83
|
+
|
|
84
|
+
// ⚠ Assumes: buy(bytes32 conditionId, uint256 amount, uint256 outcomeIndex)
|
|
85
|
+
// Verify parameter order against deployed contract ABI before use.
|
|
86
|
+
(bytes32 conditionId, uint256 amount, uint256 outcomeIndex) =
|
|
87
|
+
abi.decode(txData[4:], (bytes32, uint256, uint256));
|
|
88
|
+
|
|
89
|
+
if (!isAllowedCondition[conditionId]) return false;
|
|
90
|
+
if (amount > MAX_STAKE) return false;
|
|
91
|
+
if (!isAllowedOutcome[outcomeIndex]) return false;
|
|
92
|
+
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
function discriminator() external pure returns (bytes32) { return DISCRIMINATOR; }
|
|
97
|
+
}
|
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
// SPDX-License-Identifier: MIT
|
|
2
|
-
pragma solidity 0.8.26;
|
|
3
|
-
|
|
4
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
-
// Protocol : Aave V3
|
|
6
|
-
// Version : Pool (proxy) — fully on-chain, oracle-based liquidation
|
|
7
|
-
// Chain : Arbitrum mainnet (42161)
|
|
8
|
-
// Target : Aave V3 Pool 0x794a61358D6845594F94dc1DB02A252b5b4814aD (verified on Arbiscan)
|
|
9
|
-
//
|
|
10
|
-
// ENFORCES ON-CHAIN (kernel calls evaluate() on every dispatch; false ⇒ dispatch blocked):
|
|
11
|
-
// borrow(address asset,uint256 amount,uint256 interestRateMode,uint16 referralCode,address onBehalfOf)
|
|
12
|
-
// selector 0xa415bcad
|
|
13
|
-
// • target must be AAVE_POOL
|
|
14
|
-
// • asset must be in ALLOWED_ASSETS
|
|
15
|
-
// • amount ≤ MAX_BORROW_AMOUNT
|
|
16
|
-
// • onBehalfOf must equal ctx.account (the SMA — agent cannot borrow on behalf of others)
|
|
17
|
-
// • interestRateMode must be in ALLOWED_RATE_MODES
|
|
18
|
-
// (1 = stable [deprecated in V3.1], 2 = variable; restrict to [2] for V3.1+)
|
|
19
|
-
//
|
|
20
|
-
// AGENT-ENFORCED / NOT BOUNDED HERE (off-chain — can change without redeploying this contract):
|
|
21
|
-
// • Health factor management — the kernel cannot check post-borrow health factor
|
|
22
|
-
// • referralCode (informational only, does not affect fund safety)
|
|
23
|
-
// • Repayment timing — agent decides when to repay
|
|
24
|
-
// • Collateral composition — managed by prior deposit/supply permissions
|
|
25
|
-
//
|
|
26
|
-
// VERIFY BEFORE USE:
|
|
27
|
-
// • Confirm Aave V3 Pool address on Arbitrum (0x794a... — verify on Arbiscan).
|
|
28
|
-
// • Selector 0xa415bcad = borrow(address,uint256,uint256,uint16,address).
|
|
29
|
-
// Compute: keccak256("borrow(address,uint256,uint256,uint16,address)")[0:4]
|
|
30
|
-
// and confirm it matches before deploying.
|
|
31
|
-
// • Aave V3.1 deprecated stable-rate borrowing (interestRateMode=1).
|
|
32
|
-
// If using V3.1+, set allowedRateModes = [2] (variable only).
|
|
33
|
-
// • MAX_BORROW_AMOUNT is in the asset's base units (e.g. 6 decimals for USDC).
|
|
34
|
-
// ─────────────────────────────────────────────────────────────────────────────
|
|
35
|
-
|
|
36
|
-
import {IPermission, Context} from "@sail/interfaces/IPermission.sol";
|
|
37
|
-
|
|
38
|
-
contract BoundedBorrow_AaveV3_Arbitrum is IPermission {
|
|
39
|
-
bytes32 private constant DISCRIMINATOR = keccak256("BoundedBorrow_AaveV3_Arbitrum");
|
|
40
|
-
|
|
41
|
-
address public immutable AAVE_POOL;
|
|
42
|
-
mapping(address => bool) public isAllowedAsset;
|
|
43
|
-
uint256 public immutable MAX_BORROW_AMOUNT;
|
|
44
|
-
mapping(uint256 => bool) public isAllowedRateMode;
|
|
45
|
-
|
|
46
|
-
// borrow(address,uint256,uint256,uint16,address)
|
|
47
|
-
// VERIFY: keccak256("borrow(address,uint256,uint256,uint16,address)")[0:4] == 0xa415bcad
|
|
48
|
-
bytes4 private constant SEL_BORROW = 0xa415bcad;
|
|
49
|
-
|
|
50
|
-
/// @param aavePool Aave V3 Pool proxy address
|
|
51
|
-
/// @param allowedAssets Assets the agent may borrow
|
|
52
|
-
/// @param maxBorrowAmount Per-call borrow cap in asset base units
|
|
53
|
-
/// @param allowedRateModes Interest rate modes allowed (2 = variable; use [2] for V3.1+)
|
|
54
|
-
constructor(
|
|
55
|
-
address aavePool,
|
|
56
|
-
address[] memory allowedAssets,
|
|
57
|
-
uint256 maxBorrowAmount,
|
|
58
|
-
uint256[] memory allowedRateModes
|
|
59
|
-
) {
|
|
60
|
-
AAVE_POOL = aavePool;
|
|
61
|
-
MAX_BORROW_AMOUNT = maxBorrowAmount;
|
|
62
|
-
for (uint256 i = 0; i < allowedAssets.length; i++) {
|
|
63
|
-
isAllowedAsset[allowedAssets[i]] = true;
|
|
64
|
-
}
|
|
65
|
-
for (uint256 i = 0; i < allowedRateModes.length; i++) {
|
|
66
|
-
isAllowedRateMode[allowedRateModes[i]] = true;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
function evaluate(bytes calldata txData, Context calldata ctx) external view returns (bool) {
|
|
71
|
-
if (ctx.target != AAVE_POOL) return false;
|
|
72
|
-
if (ctx.selector != SEL_BORROW) return false;
|
|
73
|
-
// borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf)
|
|
74
|
-
// = 5 ABI-encoded 32-byte slots after the 4-byte selector
|
|
75
|
-
if (txData.length < 4 + 5 * 32) return false;
|
|
76
|
-
|
|
77
|
-
(
|
|
78
|
-
address asset,
|
|
79
|
-
uint256 amount,
|
|
80
|
-
uint256 interestRateMode,
|
|
81
|
-
/* uint16 referralCode — not bounded */,
|
|
82
|
-
address onBehalfOf
|
|
83
|
-
) = abi.decode(txData[4:], (address, uint256, uint256, uint16, address));
|
|
84
|
-
|
|
85
|
-
if (!isAllowedAsset[asset]) return false;
|
|
86
|
-
if (amount > MAX_BORROW_AMOUNT) return false;
|
|
87
|
-
if (onBehalfOf != ctx.account) return false; // agent borrows only for the SMA
|
|
88
|
-
if (!isAllowedRateMode[interestRateMode]) return false;
|
|
89
|
-
|
|
90
|
-
return true;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
function discriminator() external pure returns (bytes32) { return DISCRIMINATOR; }
|
|
94
|
-
}
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity 0.8.26;
|
|
3
|
+
|
|
4
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
5
|
+
// Protocol : Aave V3
|
|
6
|
+
// Version : Pool (proxy) — fully on-chain, oracle-based liquidation
|
|
7
|
+
// Chain : Arbitrum mainnet (42161)
|
|
8
|
+
// Target : Aave V3 Pool 0x794a61358D6845594F94dc1DB02A252b5b4814aD (verified on Arbiscan)
|
|
9
|
+
//
|
|
10
|
+
// ENFORCES ON-CHAIN (kernel calls evaluate() on every dispatch; false ⇒ dispatch blocked):
|
|
11
|
+
// borrow(address asset,uint256 amount,uint256 interestRateMode,uint16 referralCode,address onBehalfOf)
|
|
12
|
+
// selector 0xa415bcad
|
|
13
|
+
// • target must be AAVE_POOL
|
|
14
|
+
// • asset must be in ALLOWED_ASSETS
|
|
15
|
+
// • amount ≤ MAX_BORROW_AMOUNT
|
|
16
|
+
// • onBehalfOf must equal ctx.account (the SMA — agent cannot borrow on behalf of others)
|
|
17
|
+
// • interestRateMode must be in ALLOWED_RATE_MODES
|
|
18
|
+
// (1 = stable [deprecated in V3.1], 2 = variable; restrict to [2] for V3.1+)
|
|
19
|
+
//
|
|
20
|
+
// AGENT-ENFORCED / NOT BOUNDED HERE (off-chain — can change without redeploying this contract):
|
|
21
|
+
// • Health factor management — the kernel cannot check post-borrow health factor
|
|
22
|
+
// • referralCode (informational only, does not affect fund safety)
|
|
23
|
+
// • Repayment timing — agent decides when to repay
|
|
24
|
+
// • Collateral composition — managed by prior deposit/supply permissions
|
|
25
|
+
//
|
|
26
|
+
// VERIFY BEFORE USE:
|
|
27
|
+
// • Confirm Aave V3 Pool address on Arbitrum (0x794a... — verify on Arbiscan).
|
|
28
|
+
// • Selector 0xa415bcad = borrow(address,uint256,uint256,uint16,address).
|
|
29
|
+
// Compute: keccak256("borrow(address,uint256,uint256,uint16,address)")[0:4]
|
|
30
|
+
// and confirm it matches before deploying.
|
|
31
|
+
// • Aave V3.1 deprecated stable-rate borrowing (interestRateMode=1).
|
|
32
|
+
// If using V3.1+, set allowedRateModes = [2] (variable only).
|
|
33
|
+
// • MAX_BORROW_AMOUNT is in the asset's base units (e.g. 6 decimals for USDC).
|
|
34
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
35
|
+
|
|
36
|
+
import {IPermission, Context} from "@sail/interfaces/IPermission.sol";
|
|
37
|
+
|
|
38
|
+
contract BoundedBorrow_AaveV3_Arbitrum is IPermission {
|
|
39
|
+
bytes32 private constant DISCRIMINATOR = keccak256("BoundedBorrow_AaveV3_Arbitrum");
|
|
40
|
+
|
|
41
|
+
address public immutable AAVE_POOL;
|
|
42
|
+
mapping(address => bool) public isAllowedAsset;
|
|
43
|
+
uint256 public immutable MAX_BORROW_AMOUNT;
|
|
44
|
+
mapping(uint256 => bool) public isAllowedRateMode;
|
|
45
|
+
|
|
46
|
+
// borrow(address,uint256,uint256,uint16,address)
|
|
47
|
+
// VERIFY: keccak256("borrow(address,uint256,uint256,uint16,address)")[0:4] == 0xa415bcad
|
|
48
|
+
bytes4 private constant SEL_BORROW = 0xa415bcad;
|
|
49
|
+
|
|
50
|
+
/// @param aavePool Aave V3 Pool proxy address
|
|
51
|
+
/// @param allowedAssets Assets the agent may borrow
|
|
52
|
+
/// @param maxBorrowAmount Per-call borrow cap in asset base units
|
|
53
|
+
/// @param allowedRateModes Interest rate modes allowed (2 = variable; use [2] for V3.1+)
|
|
54
|
+
constructor(
|
|
55
|
+
address aavePool,
|
|
56
|
+
address[] memory allowedAssets,
|
|
57
|
+
uint256 maxBorrowAmount,
|
|
58
|
+
uint256[] memory allowedRateModes
|
|
59
|
+
) {
|
|
60
|
+
AAVE_POOL = aavePool;
|
|
61
|
+
MAX_BORROW_AMOUNT = maxBorrowAmount;
|
|
62
|
+
for (uint256 i = 0; i < allowedAssets.length; i++) {
|
|
63
|
+
isAllowedAsset[allowedAssets[i]] = true;
|
|
64
|
+
}
|
|
65
|
+
for (uint256 i = 0; i < allowedRateModes.length; i++) {
|
|
66
|
+
isAllowedRateMode[allowedRateModes[i]] = true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function evaluate(bytes calldata txData, Context calldata ctx) external view returns (bool) {
|
|
71
|
+
if (ctx.target != AAVE_POOL) return false;
|
|
72
|
+
if (ctx.selector != SEL_BORROW) return false;
|
|
73
|
+
// borrow(address asset, uint256 amount, uint256 interestRateMode, uint16 referralCode, address onBehalfOf)
|
|
74
|
+
// = 5 ABI-encoded 32-byte slots after the 4-byte selector
|
|
75
|
+
if (txData.length < 4 + 5 * 32) return false;
|
|
76
|
+
|
|
77
|
+
(
|
|
78
|
+
address asset,
|
|
79
|
+
uint256 amount,
|
|
80
|
+
uint256 interestRateMode,
|
|
81
|
+
/* uint16 referralCode — not bounded */,
|
|
82
|
+
address onBehalfOf
|
|
83
|
+
) = abi.decode(txData[4:], (address, uint256, uint256, uint16, address));
|
|
84
|
+
|
|
85
|
+
if (!isAllowedAsset[asset]) return false;
|
|
86
|
+
if (amount > MAX_BORROW_AMOUNT) return false;
|
|
87
|
+
if (onBehalfOf != ctx.account) return false; // agent borrows only for the SMA
|
|
88
|
+
if (!isAllowedRateMode[interestRateMode]) return false;
|
|
89
|
+
|
|
90
|
+
return true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
function discriminator() external pure returns (bytes32) { return DISCRIMINATOR; }
|
|
94
|
+
}
|