@oracle-agent/oracle 0.2.0 → 0.2.2
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/SETUP.md +13 -0
- package/package.json +12 -4
- package/protocols/templates/safe-erc20/SECURITY.md +16 -0
- package/protocols/templates/safe-erc20/foundry.toml +12 -0
- package/protocols/templates/safe-erc20/remappings.txt +2 -0
- package/protocols/templates/safe-erc20/src/SafeERC20.sol +53 -0
- package/protocols/templates/safe-erc20/test/SafeERC20.t.sol +72 -0
- package/public/oracle-splash/index.html +648 -598
- package/public/oracle-splash/mesh-graph.png +0 -0
- package/public/oracle-splash/mesh-graph.svg +216 -0
- package/scripts/protocol-template-gate.mjs +15 -0
- package/skills/oracle-protocol-builder/SKILL.md +45 -24
- package/src/data/catalog.mjs +9 -0
- package/src/data/desk-data.mjs +8 -0
- package/src/data/providers/poly-clob.mjs +18 -195
- package/src/protocol-templates/gate.mjs +179 -0
- package/src/protocol-templates/prepare-deploy.mjs +81 -0
package/SETUP.md
CHANGED
|
@@ -280,3 +280,16 @@ const prep = await data.call("poly-clob", "prepareOrder", {
|
|
|
280
280
|
await polySignAndSubmit(prep, { keyFile, userInitiated: true });
|
|
281
281
|
// or signViaDaemon({ surface: "poly", prepared: prep, userInitiated: true })
|
|
282
282
|
```
|
|
283
|
+
|
|
284
|
+
## Protocol templates (builder)
|
|
285
|
+
|
|
286
|
+
Gated Foundry templates under `protocols/templates/`.
|
|
287
|
+
|
|
288
|
+
```bash
|
|
289
|
+
# requires Foundry (forge)
|
|
290
|
+
cd protocols/templates/safe-erc20 && forge install && forge test
|
|
291
|
+
npm run protocol:gate -- safe-erc20
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
`prepareTemplateDeploy` will not stamp an unsigned deploy unless `forge test` passes.
|
|
295
|
+
**Not a paid security-firm audit** — see each template `SECURITY.md`.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oracle-agent/oracle",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "Oracle: prepare-only multichain agent control plane. Policy-bounded intents for a user-signed wallet. Self-custody by default
|
|
3
|
+
"version": "0.2.2",
|
|
4
|
+
"description": "Oracle: prepare-only multichain agent control plane. Policy-bounded intents for a user-signed wallet. Self-custody by default — the public package never takes your key. Built for Hermes; no model key required.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"publishConfig": {
|
|
@@ -59,7 +59,9 @@
|
|
|
59
59
|
"route": "node bin/oracle-route.mjs",
|
|
60
60
|
"scan:secrets": "node scripts/secret-scan.mjs",
|
|
61
61
|
"test:count": "node scripts/check-test-count.mjs",
|
|
62
|
-
"test:count:update": "node scripts/check-test-count.mjs --update"
|
|
62
|
+
"test:count:update": "node scripts/check-test-count.mjs --update",
|
|
63
|
+
"test:protocol-templates": "RUN_PROTOCOL_TEMPLATE_TESTS=1 node --test test/protocol-templates.test.mjs",
|
|
64
|
+
"protocol:gate": "node scripts/protocol-template-gate.mjs"
|
|
63
65
|
},
|
|
64
66
|
"dependencies": {
|
|
65
67
|
"@msgpack/msgpack": "^3.1.3",
|
|
@@ -83,6 +85,12 @@
|
|
|
83
85
|
"CONTRIBUTING.md",
|
|
84
86
|
"docs/",
|
|
85
87
|
"examples/",
|
|
86
|
-
"scripts/"
|
|
88
|
+
"scripts/",
|
|
89
|
+
"protocols/templates/**/src/**",
|
|
90
|
+
"protocols/templates/**/test/**",
|
|
91
|
+
"protocols/templates/**/foundry.toml",
|
|
92
|
+
"protocols/templates/**/remappings.txt",
|
|
93
|
+
"protocols/templates/**/SECURITY.md",
|
|
94
|
+
"src/protocol-templates/**"
|
|
87
95
|
]
|
|
88
96
|
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# SafeERC20 template security notice
|
|
2
|
+
|
|
3
|
+
**Not a paid security-firm audit.**
|
|
4
|
+
|
|
5
|
+
This template is:
|
|
6
|
+
- fixed-supply ERC20
|
|
7
|
+
- Ownable2Step + pause
|
|
8
|
+
- no tax / blacklist / upgrade proxy
|
|
9
|
+
- covered by Foundry unit tests in `test/`
|
|
10
|
+
|
|
11
|
+
Before mainnet capital:
|
|
12
|
+
1. Keep or expand Foundry tests green
|
|
13
|
+
2. Run static analysis (Slither/Aderyn) if available
|
|
14
|
+
3. Book an independent Solidity auditor for any real TVL
|
|
15
|
+
|
|
16
|
+
Oracle only prepares unsigned deploys after the JS gate confirms `forge test` passes.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.24;
|
|
3
|
+
|
|
4
|
+
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
|
5
|
+
import {ERC20Burnable} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol";
|
|
6
|
+
import {ERC20Pausable} from "@openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol";
|
|
7
|
+
import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
|
|
8
|
+
import {Ownable2Step} from "@openzeppelin/contracts/access/Ownable2Step.sol";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* @title SafeERC20
|
|
12
|
+
* @notice Opinionated fixed-supply ERC20 for Oracle protocol-builder v1.
|
|
13
|
+
*
|
|
14
|
+
* Security posture (templates, NOT a firm audit):
|
|
15
|
+
* - Fixed supply minted once to `initialHolder` in constructor (no hidden mint).
|
|
16
|
+
* - Ownable2Step ownership (no single-tx accidental transfer).
|
|
17
|
+
* - Pausable emergency stop (owner only).
|
|
18
|
+
* - No transfer tax, no blacklist, no max-tx, no trading cooldown.
|
|
19
|
+
* - No upgradeability / no proxy.
|
|
20
|
+
* - Burn optional by holders only (ERC20Burnable).
|
|
21
|
+
*
|
|
22
|
+
* This is a reviewed starter template with Foundry tests. It is NOT a paid
|
|
23
|
+
* security-firm audit. Do not put mainnet TVL on custom forks without one.
|
|
24
|
+
*/
|
|
25
|
+
contract SafeERC20 is ERC20, ERC20Burnable, ERC20Pausable, Ownable2Step {
|
|
26
|
+
constructor(
|
|
27
|
+
string memory name_,
|
|
28
|
+
string memory symbol_,
|
|
29
|
+
uint256 initialSupply,
|
|
30
|
+
address initialHolder,
|
|
31
|
+
address initialOwner
|
|
32
|
+
) ERC20(name_, symbol_) Ownable(initialOwner) {
|
|
33
|
+
require(initialHolder != address(0), "SafeERC20: holder zero");
|
|
34
|
+
require(initialOwner != address(0), "SafeERC20: owner zero");
|
|
35
|
+
require(initialSupply > 0, "SafeERC20: supply zero");
|
|
36
|
+
_mint(initialHolder, initialSupply);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function pause() external onlyOwner {
|
|
40
|
+
_pause();
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
function unpause() external onlyOwner {
|
|
44
|
+
_unpause();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function _update(address from, address to, uint256 value)
|
|
48
|
+
internal
|
|
49
|
+
override(ERC20, ERC20Pausable)
|
|
50
|
+
{
|
|
51
|
+
super._update(from, to, value);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// SPDX-License-Identifier: MIT
|
|
2
|
+
pragma solidity ^0.8.24;
|
|
3
|
+
|
|
4
|
+
import {Test} from "forge-std/Test.sol";
|
|
5
|
+
import {SafeERC20} from "../src/SafeERC20.sol";
|
|
6
|
+
|
|
7
|
+
contract SafeERC20Test is Test {
|
|
8
|
+
SafeERC20 internal token;
|
|
9
|
+
address internal owner = makeAddr("owner");
|
|
10
|
+
address internal holder = makeAddr("holder");
|
|
11
|
+
address internal alice = makeAddr("alice");
|
|
12
|
+
address internal bob = makeAddr("bob");
|
|
13
|
+
|
|
14
|
+
uint256 internal constant SUPPLY = 1_000_000 ether;
|
|
15
|
+
|
|
16
|
+
function setUp() public {
|
|
17
|
+
token = new SafeERC20("Safe", "SAFE", SUPPLY, holder, owner);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function test_fixedSupply_noHiddenMint() public view {
|
|
21
|
+
assertEq(token.totalSupply(), SUPPLY);
|
|
22
|
+
assertEq(token.balanceOf(holder), SUPPLY);
|
|
23
|
+
assertEq(token.balanceOf(owner), 0);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function test_transfer_noTax() public {
|
|
27
|
+
vm.prank(holder);
|
|
28
|
+
token.transfer(alice, 100 ether);
|
|
29
|
+
assertEq(token.balanceOf(alice), 100 ether);
|
|
30
|
+
assertEq(token.balanceOf(holder), SUPPLY - 100 ether);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function test_pause_blocksTransfers() public {
|
|
34
|
+
vm.prank(owner);
|
|
35
|
+
token.pause();
|
|
36
|
+
vm.prank(holder);
|
|
37
|
+
vm.expectRevert();
|
|
38
|
+
token.transfer(alice, 1 ether);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function test_onlyOwner_canPause() public {
|
|
42
|
+
vm.prank(alice);
|
|
43
|
+
vm.expectRevert();
|
|
44
|
+
token.pause();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function test_ownable2Step_requiresAccept() public {
|
|
48
|
+
vm.prank(owner);
|
|
49
|
+
token.transferOwnership(alice);
|
|
50
|
+
// still owner until accept
|
|
51
|
+
assertEq(token.owner(), owner);
|
|
52
|
+
vm.prank(alice);
|
|
53
|
+
token.acceptOwnership();
|
|
54
|
+
assertEq(token.owner(), alice);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function test_burn_reducesSupply() public {
|
|
58
|
+
vm.prank(holder);
|
|
59
|
+
token.burn(10 ether);
|
|
60
|
+
assertEq(token.totalSupply(), SUPPLY - 10 ether);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function test_rejectZeroHolder() public {
|
|
64
|
+
vm.expectRevert(bytes("SafeERC20: holder zero"));
|
|
65
|
+
new SafeERC20("X", "X", SUPPLY, address(0), owner);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
function test_rejectZeroSupply() public {
|
|
69
|
+
vm.expectRevert(bytes("SafeERC20: supply zero"));
|
|
70
|
+
new SafeERC20("X", "X", 0, holder, owner);
|
|
71
|
+
}
|
|
72
|
+
}
|