MAIEV
by thesecretlab
MAIEV
by thesecretlab
Audit Report evmbench-20260220-133143
Styled to match thesecretlab visual direction and issued by MAIEV.
FAILED
Launch Signal: Run incomplete / review required
No findings detected in this run. Evidence package is clean for current scope.
No findings detected in this run. Evidence package is clean for current scope.
Error: Codex runner failed with code=1:
Start Here (60-Second Read)
This section explains what passed, what failed, and where to drill down.
What This Run Means
- Scope: 15 contracts reviewed across 7 labeled systems.
- Risk: No findings detected in this run. Evidence package is clean for current scope.
- Coverage: Suite coverage file not available.
- Evidence: Raw logs, digests, and source snapshots are attached in Diagnostics.
How To Read Colors
PASS: Safe in scope
WARN: Review before launch
FAIL: Blocker
Step 1
Check launch signal and findings count.
Step 2
Open Findings tab for exact risk details.
Step 3
Use Diagnostics for proof logs and artifacts.
Findings
0
Critical
0
High
0
Suite Gaps
0
Timeline Events
0
Contracts Reviewed
15
Economic Overlay (thesecretlab)
Latest coherence + flywheel + VM/privacy runs linked into this audit archive.
| Track | Latest Run | Status | Key Metrics | Artifacts |
|---|---|---|---|---|
| Economic Coherence | econ-20260220-142514 | FAILED | Checks 6/9, Reference Trade 100 VAI @ 5.034% | json | md |
| Flywheel Runtime | flywheel-20260220-145840 | PASS | Checks 10/10, Findings 2, Critical 0 | json | md |
| VM Privacy | vmprivacy-20260220-155511 | PASS | Checks 5/5, Findings 0, Mechanisms 5/5 | json | md |
Execution Timeline
Polling every n/as
| # | Polled At | Status Trace |
|---|---|---|
| No polling timeline captured for this run. | ||
VAI/DAI Full Suite Coverage
Missing Components: 0 / 0
| # | Contract | Component | Presence | Notes |
|---|---|---|---|---|
| No VAI/DAI suite coverage file found for this run. | ||||
Contract Coverage Labels
Label Groups: 7
| # | Contract | Label | Audit Status |
|---|---|---|---|
| 1 | Clip.sol |
EVM Core Contract | FAILED |
| 2 | DaiJoin.sol |
EVM Core Contract | FAILED |
| 3 | Dog.sol |
EVM Core Contract | FAILED |
| 4 | GemJoin.sol |
EVM Core Contract | FAILED |
| 5 | Jug.sol |
EVM Core Contract | FAILED |
| 6 | Pot.sol |
EVM Core Contract | FAILED |
| 7 | Spot.sol |
EVM Core Contract | FAILED |
| 8 | Vat.sol |
EVM Core Contract | FAILED |
| 9 | VeilKeep3r.sol |
EVM Keep3r | FAILED |
| 10 | VeilLiquidityIntentGateway.sol |
EVM Intent Gateway (Liquidity) | FAILED |
| 11 | VeilOrderIntentGateway.sol |
EVM Intent Gateway (Order) | FAILED |
| 12 | VeilTreasury.sol |
EVM Treasury | FAILED |
| 13 | VeilUniV2Dex.sol |
EVM UniV2 LP/DEX | FAILED |
| 14 | VeilVAI.sol |
EVM VAI | FAILED |
| 15 | Vow.sol |
EVM Core Contract | FAILED |
Findings Breakdown
Contract Scope: C:\Users\Josh\hypersdk\examples\veilvm\companion-evm\contracts
| # | Title | Severity | Location | Details |
|---|---|---|---|---|
| No vulnerabilities reported. This run is clean against the current audit prompt and contract scope. | ||||
Contract Integrity Proof
SHA256 + line/byte counts of audited source
| # | Contract | Label | Lines | Bytes | SHA256 |
|---|---|---|---|---|---|
| No contract digest file found for this run. | |||||
Code Under Audit (With Commentary)
Exact source snapshot with reviewer focus notes
Clip.sol
EVM Core Contract
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | /// @notice Minimal collateral auction house inspired by Maker `Clip`.
5 | contract Clip {
6 | event Rely(address indexed usr);
7 | event Deny(address indexed usr);
8 | event File(bytes32 indexed what, uint256 data);
9 | event File(bytes32 indexed what, address data);
10 | event Kick(uint256 indexed id, address indexed usr, uint256 lot, uint256 tab);
11 | event Take(uint256 indexed id, address indexed to, uint256 lot, uint256 cost);
12 | event Yank(uint256 indexed id);
13 |
14 | error ClipAuth();
15 | error ClipBounds();
16 |
17 | struct Sale {
18 | address usr;
19 | uint256 lot;
20 | uint256 tab;
21 | bool active;
22 | }
23 |
24 | mapping(address => uint256) public wards;
25 | mapping(uint256 => Sale) public sales;
26 | uint256 public kicks;
27 |
28 | address public vow;
29 | address public dog;
30 | address public spotter;
31 | uint256 public chip;
32 | uint256 public tip;
33 | uint256 public tail;
34 | uint256 public buf = 1e18;
35 |
36 | bytes32 private constant WHAT_VOW = keccak256("vow");
37 | bytes32 private constant WHAT_DOG = keccak256("dog");
38 | bytes32 private constant WHAT_SPOTTER = keccak256("spotter");
39 | bytes32 private constant WHAT_CHIP = keccak256("chip");
40 | bytes32 private constant WHAT_TIP = keccak256("tip");
41 | bytes32 private constant WHAT_TAIL = keccak256("tail");
42 | bytes32 private constant WHAT_BUF = keccak256("buf");
43 |
44 | modifier auth() {
45 | if (wards[msg.sender] != 1) revert ClipAuth();
46 | _;
47 | }
48 |
49 | constructor(address owner_) {
50 | wards[owner_] = 1;
51 | emit Rely(owner_);
52 | }
53 |
54 | function rely(address usr) external auth {
55 | wards[usr] = 1;
56 | emit Rely(usr);
57 | }
58 |
59 | function deny(address usr) external auth {
60 | wards[usr] = 0;
61 | emit Deny(usr);
62 | }
63 |
64 | function file(bytes32 what, uint256 data) external auth {
65 | if (what == WHAT_CHIP) {
66 | chip = data;
67 | } else if (what == WHAT_TIP) {
68 | tip = data;
69 | } else if (what == WHAT_TAIL) {
70 | tail = data;
71 | } else if (what == WHAT_BUF) {
72 | buf = data;
73 | } else {
74 | revert ClipBounds();
75 | }
76 | emit File(what, data);
77 | }
78 |
79 | function file(bytes32 what, address data) external auth {
80 | if (what == WHAT_VOW) {
81 | vow = data;
82 | } else if (what == WHAT_DOG) {
83 | dog = data;
84 | } else if (what == WHAT_SPOTTER) {
85 | spotter = data;
86 | } else {
87 | revert ClipBounds();
88 | }
89 | emit File(what, data);
90 | }
91 |
92 | function kick(address usr, uint256 lot, uint256 tab) external auth returns (uint256 id) {
93 | if (lot == 0 || tab == 0) revert ClipBounds();
94 | unchecked {
95 | id = ++kicks;
96 | }
97 | sales[id] = Sale({
98 | usr: usr,
99 | lot: lot,
100 | tab: tab,
101 | active: true
102 | });
103 | emit Kick(id, usr, lot, tab);
104 | }
105 |
106 | function take(uint256 id, uint256 lot, uint256 maxPrice, address to) external returns (uint256 cost) {
107 | Sale storage s = sales[id];
108 | if (!s.active || lot == 0 || to == address(0)) revert ClipBounds();
109 | uint256 fill = lot > s.lot ? s.lot : lot;
110 | cost = (fill * maxPrice) / 1e18;
111 | if (cost > s.tab) {
112 | cost = s.tab;
113 | }
114 | unchecked {
115 | s.lot -= fill;
116 | s.tab -= cost;
117 | }
118 | if (s.lot == 0 || s.tab == 0) {
119 | s.active = false;
120 | }
121 | emit Take(id, to, fill, cost);
122 | }
123 |
124 | function yank(uint256 id) external auth {
125 | Sale storage s = sales[id];
126 | if (!s.active) revert ClipBounds();
127 | s.active = false;
128 | emit Yank(id);
129 | }
130 | }
131 |
132 |
DaiJoin.sol
EVM Core Contract
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | interface IERC20LikeDaiJoin {
5 | function transfer(address to, uint256 value) external returns (bool);
6 | function transferFrom(address from, address to, uint256 value) external returns (bool);
7 | function decimals() external view returns (uint8);
8 | }
9 |
10 | interface IVatLikeDaiJoin {
11 | function move(address src, address dst, uint256 rad) external;
12 | }
13 |
14 | /// @notice Minimal stablecoin adapter inspired by Maker `DaiJoin`.
15 | contract DaiJoin {
16 | event Rely(address indexed usr);
17 | event Deny(address indexed usr);
18 | event Cage();
19 | event Join(address indexed usr, uint256 wad);
20 | event Exit(address indexed usr, uint256 wad);
21 |
22 | error DaiJoinAuth();
23 | error DaiJoinBounds();
24 | error DaiJoinTransferFailed();
25 |
26 | mapping(address => uint256) public wards;
27 | IVatLikeDaiJoin public immutable vat;
28 | IERC20LikeDaiJoin public immutable dai;
29 | uint256 public immutable one;
30 | uint256 public live = 1;
31 |
32 | modifier auth() {
33 | if (wards[msg.sender] != 1) revert DaiJoinAuth();
34 | _;
35 | }
36 |
37 | constructor(address vat_, address dai_, address owner_) {
38 | uint8 dec = IERC20LikeDaiJoin(dai_).decimals();
39 | if (dec > 27) revert DaiJoinBounds();
40 | wards[owner_] = 1;
41 | emit Rely(owner_);
42 | vat = IVatLikeDaiJoin(vat_);
43 | dai = IERC20LikeDaiJoin(dai_);
44 | one = 10 ** (27 - dec);
45 | }
46 |
47 | function rely(address usr) external auth {
48 | wards[usr] = 1;
49 | emit Rely(usr);
50 | }
51 |
52 | function deny(address usr) external auth {
53 | wards[usr] = 0;
54 | emit Deny(usr);
55 | }
56 |
57 | function cage() external auth {
58 | live = 0;
59 | emit Cage();
60 | }
61 |
62 | function join(address usr, uint256 wad) external {
63 | if (live != 1) revert DaiJoinBounds();
64 | if (!dai.transferFrom(msg.sender, address(this), wad)) revert DaiJoinTransferFailed();
65 | vat.move(address(this), usr, wad * one);
66 | emit Join(usr, wad);
67 | }
68 |
69 | function exit(address usr, uint256 wad) external {
70 | vat.move(msg.sender, address(this), wad * one);
71 | if (!dai.transfer(usr, wad)) revert DaiJoinTransferFailed();
72 | emit Exit(usr, wad);
73 | }
74 | }
75 |
76 |
Dog.sol
EVM Core Contract
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | /// @notice Minimal liquidation trigger inspired by Maker `Dog`.
5 | contract Dog {
6 | event Rely(address indexed usr);
7 | event Deny(address indexed usr);
8 | event File(bytes32 indexed what, uint256 data);
9 | event File(bytes32 indexed ilk, bytes32 indexed what, uint256 data);
10 | event File(bytes32 indexed ilk, bytes32 indexed what, address data);
11 | event Bark(bytes32 indexed ilk, address indexed urn, uint256 lot, uint256 tab);
12 |
13 | error DogAuth();
14 | error DogBounds();
15 |
16 | struct Ilk {
17 | address clip;
18 | uint256 chop;
19 | uint256 hole;
20 | uint256 dirt;
21 | }
22 |
23 | mapping(address => uint256) public wards;
24 | mapping(bytes32 => Ilk) public ilks;
25 |
26 | uint256 public Hole;
27 | uint256 public Dirt;
28 | uint256 public live = 1;
29 |
30 | bytes32 private constant WHAT_HOLE = keccak256("Hole");
31 | bytes32 private constant WHAT_LIVE = keccak256("live");
32 | bytes32 private constant WHAT_CLIP = keccak256("clip");
33 | bytes32 private constant WHAT_CHOP = keccak256("chop");
34 | bytes32 private constant WHAT_ILK_HOLE = keccak256("hole");
35 |
36 | modifier auth() {
37 | if (wards[msg.sender] != 1) revert DogAuth();
38 | _;
39 | }
40 |
41 | constructor(address owner_) {
42 | wards[owner_] = 1;
43 | emit Rely(owner_);
44 | }
45 |
46 | function rely(address usr) external auth {
47 | wards[usr] = 1;
48 | emit Rely(usr);
49 | }
50 |
51 | function deny(address usr) external auth {
52 | wards[usr] = 0;
53 | emit Deny(usr);
54 | }
55 |
56 | function file(bytes32 what, uint256 data) external auth {
57 | if (what == WHAT_HOLE) {
58 | Hole = data;
59 | } else if (what == WHAT_LIVE) {
60 | live = data;
61 | } else {
62 | revert DogBounds();
63 | }
64 | emit File(what, data);
65 | }
66 |
67 | function file(bytes32 ilk, bytes32 what, uint256 data) external auth {
68 | if (what == WHAT_CHOP) {
69 | ilks[ilk].chop = data;
70 | } else if (what == WHAT_ILK_HOLE) {
71 | ilks[ilk].hole = data;
72 | } else {
73 | revert DogBounds();
74 | }
75 | emit File(ilk, what, data);
76 | }
77 |
78 | function file(bytes32 ilk, bytes32 what, address data) external auth {
79 | if (what != WHAT_CLIP) revert DogBounds();
80 | ilks[ilk].clip = data;
81 | emit File(ilk, what, data);
82 | }
83 |
84 | function bark(bytes32 ilk, address urn, uint256 lot, uint256 tab) external auth {
85 | if (live == 0) revert DogBounds();
86 | Ilk storage i = ilks[ilk];
87 | uint256 next = Dirt + tab;
88 | if (Hole > 0 && next > Hole) revert DogBounds();
89 | if (i.hole > 0 && i.dirt + tab > i.hole) revert DogBounds();
90 | Dirt = next;
91 | i.dirt += tab;
92 | emit Bark(ilk, urn, lot, tab);
93 | }
94 | }
95 |
96 |
GemJoin.sol
EVM Core Contract
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | interface IERC20LikeGemJoin {
5 | function transfer(address to, uint256 value) external returns (bool);
6 | function transferFrom(address from, address to, uint256 value) external returns (bool);
7 | function decimals() external view returns (uint8);
8 | }
9 |
10 | interface IVatLikeGemJoin {
11 | function slip(bytes32 ilk, address usr, int256 wad) external;
12 | }
13 |
14 | /// @notice Minimal collateral adapter inspired by Maker `GemJoin`.
15 | contract GemJoin {
16 | event Rely(address indexed usr);
17 | event Deny(address indexed usr);
18 | event Cage();
19 | event Join(address indexed usr, uint256 wad);
20 | event Exit(address indexed usr, uint256 wad);
21 |
22 | error GemJoinAuth();
23 | error GemJoinBounds();
24 | error GemJoinTransferFailed();
25 |
26 | mapping(address => uint256) public wards;
27 | IVatLikeGemJoin public immutable vat;
28 | bytes32 public immutable ilk;
29 | IERC20LikeGemJoin public immutable gem;
30 | uint8 public immutable dec;
31 | uint256 public live = 1;
32 |
33 | modifier auth() {
34 | if (wards[msg.sender] != 1) revert GemJoinAuth();
35 | _;
36 | }
37 |
38 | constructor(address vat_, bytes32 ilk_, address gem_, address owner_) {
39 | wards[owner_] = 1;
40 | emit Rely(owner_);
41 | vat = IVatLikeGemJoin(vat_);
42 | ilk = ilk_;
43 | gem = IERC20LikeGemJoin(gem_);
44 | dec = IERC20LikeGemJoin(gem_).decimals();
45 | }
46 |
47 | function rely(address usr) external auth {
48 | wards[usr] = 1;
49 | emit Rely(usr);
50 | }
51 |
52 | function deny(address usr) external auth {
53 | wards[usr] = 0;
54 | emit Deny(usr);
55 | }
56 |
57 | function cage() external auth {
58 | live = 0;
59 | emit Cage();
60 | }
61 |
62 | function join(address usr, uint256 wad) external {
63 | if (live != 1) revert GemJoinBounds();
64 | if (!gem.transferFrom(msg.sender, address(this), wad)) revert GemJoinTransferFailed();
65 | vat.slip(ilk, usr, int256(wad));
66 | emit Join(usr, wad);
67 | }
68 |
69 | function exit(address usr, uint256 wad) external {
70 | vat.slip(ilk, msg.sender, -int256(wad));
71 | if (!gem.transfer(usr, wad)) revert GemJoinTransferFailed();
72 | emit Exit(usr, wad);
73 | }
74 | }
75 |
76 |
Jug.sol
EVM Core Contract
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | interface IVatJug {
5 | function file(bytes32 ilk, bytes32 what, uint256 data) external;
6 | }
7 |
8 | /// @notice Minimal stability-fee module inspired by Maker `Jug`.
9 | contract Jug {
10 | event Rely(address indexed usr);
11 | event Deny(address indexed usr);
12 | event File(bytes32 indexed what, uint256 data);
13 | event File(bytes32 indexed ilk, bytes32 indexed what, uint256 data);
14 | event Drip(bytes32 indexed ilk, uint256 nextRate, uint256 at);
15 |
16 | error JugAuth();
17 | error JugBounds();
18 |
19 | mapping(address => uint256) public wards;
20 | mapping(bytes32 => uint256) public duty;
21 | mapping(bytes32 => uint256) public rho;
22 |
23 | IVatJug public immutable vat;
24 | uint256 public base;
25 |
26 | bytes32 private constant WHAT_BASE = keccak256("base");
27 | bytes32 private constant WHAT_DUTY = keccak256("duty");
28 | bytes32 private constant WHAT_RHO = keccak256("rho");
29 | bytes32 private constant WHAT_RATE = keccak256("rate");
30 |
31 | modifier auth() {
32 | if (wards[msg.sender] != 1) revert JugAuth();
33 | _;
34 | }
35 |
36 | constructor(address vat_, address owner_) {
37 | vat = IVatJug(vat_);
38 | wards[owner_] = 1;
39 | emit Rely(owner_);
40 | }
41 |
42 | function rely(address usr) external auth {
43 | wards[usr] = 1;
44 | emit Rely(usr);
45 | }
46 |
47 | function deny(address usr) external auth {
48 | wards[usr] = 0;
49 | emit Deny(usr);
50 | }
51 |
52 | function file(bytes32 what, uint256 data) external auth {
53 | if (what != WHAT_BASE) revert JugBounds();
54 | base = data;
55 | emit File(what, data);
56 | }
57 |
58 | function file(bytes32 ilk, bytes32 what, uint256 data) external auth {
59 | if (what == WHAT_DUTY) {
60 | duty[ilk] = data;
61 | } else if (what == WHAT_RHO) {
62 | rho[ilk] = data;
63 | } else {
64 | revert JugBounds();
65 | }
66 | emit File(ilk, what, data);
67 | }
68 |
69 | function drip(bytes32 ilk) external returns (uint256 nextRate) {
70 | uint256 prev = rho[ilk];
71 | if (prev == 0) prev = block.timestamp;
72 | if (block.timestamp < prev) revert JugBounds();
73 | unchecked {
74 | rho[ilk] = block.timestamp;
75 | nextRate = base + duty[ilk];
76 | }
77 | vat.file(ilk, WHAT_RATE, nextRate);
78 | emit Drip(ilk, nextRate, block.timestamp);
79 | }
80 | }
81 |
82 |
Pot.sol
EVM Core Contract
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | /// @notice Minimal savings-rate module inspired by Maker `Pot`.
5 | contract Pot {
6 | event Rely(address indexed usr);
7 | event Deny(address indexed usr);
8 | event File(bytes32 indexed what, uint256 data);
9 | event Drip(uint256 nextChi, uint256 at);
10 | event Join(address indexed usr, uint256 wad);
11 | event Exit(address indexed usr, uint256 wad);
12 |
13 | error PotAuth();
14 | error PotBounds();
15 |
16 | mapping(address => uint256) public wards;
17 | mapping(address => uint256) public pie;
18 |
19 | uint256 public Pie;
20 | uint256 public dsr = 1e27;
21 | uint256 public chi = 1e27;
22 | uint256 public rho;
23 |
24 | bytes32 private constant WHAT_DSR = keccak256("dsr");
25 |
26 | modifier auth() {
27 | if (wards[msg.sender] != 1) revert PotAuth();
28 | _;
29 | }
30 |
31 | constructor(address owner_) {
32 | wards[owner_] = 1;
33 | rho = block.timestamp;
34 | emit Rely(owner_);
35 | }
36 |
37 | function rely(address usr) external auth {
38 | wards[usr] = 1;
39 | emit Rely(usr);
40 | }
41 |
42 | function deny(address usr) external auth {
43 | wards[usr] = 0;
44 | emit Deny(usr);
45 | }
46 |
47 | function file(bytes32 what, uint256 data) external auth {
48 | if (what != WHAT_DSR) revert PotBounds();
49 | dsr = data;
50 | emit File(what, data);
51 | }
52 |
53 | function drip() public returns (uint256 nextChi) {
54 | uint256 dt = block.timestamp - rho;
55 | if (dt > 0) {
56 | // Simplified accrual model for local companion usage.
57 | nextChi = chi + ((chi * (dsr - 1e27) * dt) / 1e27);
58 | chi = nextChi;
59 | rho = block.timestamp;
60 | } else {
61 | nextChi = chi;
62 | }
63 | emit Drip(nextChi, rho);
64 | }
65 |
66 | function join(uint256 wad) external {
67 | drip();
68 | pie[msg.sender] += wad;
69 | Pie += wad;
70 | emit Join(msg.sender, wad);
71 | }
72 |
73 | function exit(uint256 wad) external {
74 | uint256 p = pie[msg.sender];
75 | if (p < wad) revert PotBounds();
76 | unchecked {
77 | pie[msg.sender] = p - wad;
78 | Pie -= wad;
79 | }
80 | emit Exit(msg.sender, wad);
81 | }
82 | }
83 |
84 |
Spot.sol
EVM Core Contract
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | /// @notice Minimal oracle/spot module inspired by Maker `Spot`.
5 | contract Spot {
6 | event Rely(address indexed usr);
7 | event Deny(address indexed usr);
8 | event File(bytes32 indexed what, uint256 data);
9 | event File(bytes32 indexed ilk, bytes32 indexed what, uint256 data);
10 | event File(bytes32 indexed ilk, bytes32 indexed what, address data);
11 | event Poke(bytes32 indexed ilk, uint256 price);
12 |
13 | error SpotAuth();
14 | error SpotBounds();
15 |
16 | struct Ilk {
17 | address pip;
18 | uint256 mat;
19 | uint256 price;
20 | }
21 |
22 | mapping(address => uint256) public wards;
23 | mapping(bytes32 => Ilk) public ilks;
24 | uint256 public par = 1e27;
25 |
26 | bytes32 private constant WHAT_PAR = keccak256("par");
27 | bytes32 private constant WHAT_MAT = keccak256("mat");
28 | bytes32 private constant WHAT_PIP = keccak256("pip");
29 |
30 | modifier auth() {
31 | if (wards[msg.sender] != 1) revert SpotAuth();
32 | _;
33 | }
34 |
35 | constructor(address owner_) {
36 | wards[owner_] = 1;
37 | emit Rely(owner_);
38 | }
39 |
40 | function rely(address usr) external auth {
41 | wards[usr] = 1;
42 | emit Rely(usr);
43 | }
44 |
45 | function deny(address usr) external auth {
46 | wards[usr] = 0;
47 | emit Deny(usr);
48 | }
49 |
50 | function file(bytes32 what, uint256 data) external auth {
51 | if (what != WHAT_PAR) revert SpotBounds();
52 | par = data;
53 | emit File(what, data);
54 | }
55 |
56 | function file(bytes32 ilk, bytes32 what, uint256 data) external auth {
57 | if (what != WHAT_MAT) revert SpotBounds();
58 | ilks[ilk].mat = data;
59 | emit File(ilk, what, data);
60 | }
61 |
62 | function file(bytes32 ilk, bytes32 what, address data) external auth {
63 | if (what != WHAT_PIP) revert SpotBounds();
64 | ilks[ilk].pip = data;
65 | emit File(ilk, what, data);
66 | }
67 |
68 | function poke(bytes32 ilk, uint256 price) external auth {
69 | ilks[ilk].price = price;
70 | emit Poke(ilk, price);
71 | }
72 | }
73 |
74 |
Vat.sol
EVM Core Contract
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | /// @notice Minimal companion accounting core inspired by Maker `Vat`.
5 | /// @dev Scoped for local VEIL economic integration and audit coverage.
6 | contract Vat {
7 | event Rely(address indexed usr);
8 | event Deny(address indexed usr);
9 | event File(bytes32 indexed what, uint256 data);
10 | event File(bytes32 indexed ilk, bytes32 indexed what, uint256 data);
11 | event Slip(bytes32 indexed ilk, address indexed usr, int256 wad);
12 | event Move(address indexed src, address indexed dst, uint256 rad);
13 | event Suck(address indexed u, address indexed v, uint256 rad);
14 | event Heal(uint256 rad);
15 |
16 | error VatAuth();
17 | error VatBounds();
18 |
19 | mapping(address => uint256) public wards;
20 | mapping(bytes32 => mapping(address => uint256)) public gem;
21 | mapping(address => uint256) public dai;
22 | mapping(address => uint256) public sin;
23 | mapping(bytes32 => uint256) public rate;
24 | mapping(bytes32 => uint256) public spot;
25 | mapping(bytes32 => uint256) public lineByIlk;
26 |
27 | uint256 public Line;
28 | uint256 public debt;
29 | uint256 public live = 1;
30 |
31 | bytes32 private constant WHAT_LINE = keccak256("line");
32 | bytes32 private constant WHAT_LIVE = keccak256("live");
33 | bytes32 private constant WHAT_RATE = keccak256("rate");
34 | bytes32 private constant WHAT_SPOT = keccak256("spot");
35 | bytes32 private constant WHAT_ILK_LINE = keccak256("line");
36 |
37 | modifier auth() {
38 | if (wards[msg.sender] != 1) revert VatAuth();
39 | _;
40 | }
41 |
42 | constructor(address owner_) {
43 | wards[owner_] = 1;
44 | emit Rely(owner_);
45 | }
46 |
47 | function rely(address usr) external auth {
48 | wards[usr] = 1;
49 | emit Rely(usr);
50 | }
51 |
52 | function deny(address usr) external auth {
53 | wards[usr] = 0;
54 | emit Deny(usr);
55 | }
56 |
57 | function file(bytes32 what, uint256 data) external auth {
58 | if (what == WHAT_LINE) {
59 | Line = data;
60 | } else if (what == WHAT_LIVE) {
61 | live = data;
62 | } else {
63 | revert VatBounds();
64 | }
65 | emit File(what, data);
66 | }
67 |
68 | function file(bytes32 ilk, bytes32 what, uint256 data) external auth {
69 | if (what == WHAT_RATE) {
70 | rate[ilk] = data;
71 | } else if (what == WHAT_SPOT) {
72 | spot[ilk] = data;
73 | } else if (what == WHAT_ILK_LINE) {
74 | lineByIlk[ilk] = data;
75 | } else {
76 | revert VatBounds();
77 | }
78 | emit File(ilk, what, data);
79 | }
80 |
81 | function slip(bytes32 ilk, address usr, int256 wad) external auth {
82 | if (wad >= 0) {
83 | gem[ilk][usr] += uint256(wad);
84 | } else {
85 | uint256 down = uint256(-wad);
86 | uint256 bal = gem[ilk][usr];
87 | if (bal < down) revert VatBounds();
88 | unchecked {
89 | gem[ilk][usr] = bal - down;
90 | }
91 | }
92 | emit Slip(ilk, usr, wad);
93 | }
94 |
95 | function move(address src, address dst, uint256 rad) external {
96 | if (msg.sender != src && wards[msg.sender] != 1) revert VatAuth();
97 | uint256 bal = dai[src];
98 | if (bal < rad) revert VatBounds();
99 | unchecked {
100 | dai[src] = bal - rad;
101 | dai[dst] += rad;
102 | }
103 | emit Move(src, dst, rad);
104 | }
105 |
106 | function suck(address u, address v, uint256 rad) external auth {
107 | unchecked {
108 | dai[u] += rad;
109 | sin[v] += rad;
110 | debt += rad;
111 | }
112 | emit Suck(u, v, rad);
113 | }
114 |
115 | function heal(uint256 rad) external {
116 | uint256 d = dai[msg.sender];
117 | uint256 s = sin[msg.sender];
118 | if (d < rad || s < rad || debt < rad) revert VatBounds();
119 | unchecked {
120 | dai[msg.sender] = d - rad;
121 | sin[msg.sender] = s - rad;
122 | debt -= rad;
123 | }
124 | emit Heal(rad);
125 | }
126 | }
127 |
128 |
VeilKeep3r.sol
EVM Keep3r
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | interface IERC20LikeKeep3r {
5 | function balanceOf(address account) external view returns (uint256);
6 | function transfer(address to, uint256 value) external returns (bool);
7 | function transferFrom(address from, address to, uint256 value) external returns (bool);
8 | }
9 |
10 | /// @notice Fast companion EVM Keep3r-style registry and payout rail.
11 | /// @dev Lightweight fork surface for VEIL local/ops workflows.
12 | contract VeilKeep3r {
13 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
14 | event JobSet(address indexed job, bool enabled);
15 | event MinimumBondSet(uint256 previousMinimumBond, uint256 nextMinimumBond);
16 | event Bonded(address indexed keeper, uint256 amount, uint256 bondedTotal);
17 | event Unbonded(address indexed keeper, uint256 amount, uint256 bondedTotal);
18 | event Funded(address indexed from, uint256 amount);
19 | event Worked(address indexed job, address indexed keeper, uint256 amount);
20 | event Slashed(address indexed keeper, address indexed recipient, uint256 amount);
21 |
22 | error Keep3rZeroAddress();
23 | error Keep3rOnlyOwner();
24 | error Keep3rOnlyJob();
25 | error Keep3rInvalidAmount();
26 | error Keep3rTransferFailed();
27 | error Keep3rInsufficientBond();
28 | error Keep3rNotActiveKeeper();
29 | error Keep3rInsufficientCredits();
30 |
31 | IERC20LikeKeep3r public immutable VEIL;
32 | address public owner;
33 | uint256 public minimumBond;
34 | uint256 public totalBonded;
35 |
36 | mapping(address => bool) public jobs;
37 | mapping(address => uint256) public keeperBond;
38 |
39 | modifier onlyOwner() {
40 | if (msg.sender != owner) revert Keep3rOnlyOwner();
41 | _;
42 | }
43 |
44 | modifier onlyJob() {
45 | if (!jobs[msg.sender]) revert Keep3rOnlyJob();
46 | _;
47 | }
48 |
49 | constructor(address veilToken_, uint256 minimumBond_, address owner_) {
50 | if (veilToken_ == address(0) || owner_ == address(0)) revert Keep3rZeroAddress();
51 | VEIL = IERC20LikeKeep3r(veilToken_);
52 | minimumBond = minimumBond_;
53 | owner = owner_;
54 | emit OwnershipTransferred(address(0), owner_);
55 | }
56 |
57 | function transferOwnership(address nextOwner) external onlyOwner {
58 | if (nextOwner == address(0)) revert Keep3rZeroAddress();
59 | emit OwnershipTransferred(owner, nextOwner);
60 | owner = nextOwner;
61 | }
62 |
63 | function setJob(address job, bool enabled) external onlyOwner {
64 | if (job == address(0)) revert Keep3rZeroAddress();
65 | jobs[job] = enabled;
66 | emit JobSet(job, enabled);
67 | }
68 |
69 | function setMinimumBond(uint256 nextMinimumBond) external onlyOwner {
70 | uint256 previous = minimumBond;
71 | minimumBond = nextMinimumBond;
72 | emit MinimumBondSet(previous, nextMinimumBond);
73 | }
74 |
75 | function isKeeper(address keeper) public view returns (bool) {
76 | return keeperBond[keeper] >= minimumBond;
77 | }
78 |
79 | function availableCredits() public view returns (uint256) {
80 | uint256 bal = VEIL.balanceOf(address(this));
81 | if (bal <= totalBonded) {
82 | return 0;
83 | }
84 | return bal - totalBonded;
85 | }
86 |
87 | function fund(uint256 amount) external {
88 | if (amount == 0) revert Keep3rInvalidAmount();
89 | if (!VEIL.transferFrom(msg.sender, address(this), amount)) {
90 | revert Keep3rTransferFailed();
91 | }
92 | emit Funded(msg.sender, amount);
93 | }
94 |
95 | function bond(uint256 amount) external {
96 | if (amount == 0) revert Keep3rInvalidAmount();
97 | if (!VEIL.transferFrom(msg.sender, address(this), amount)) {
98 | revert Keep3rTransferFailed();
99 | }
100 | keeperBond[msg.sender] += amount;
101 | totalBonded += amount;
102 | emit Bonded(msg.sender, amount, keeperBond[msg.sender]);
103 | }
104 |
105 | function unbond(uint256 amount) external {
106 | if (amount == 0) revert Keep3rInvalidAmount();
107 | uint256 bonded = keeperBond[msg.sender];
108 | if (bonded < amount) revert Keep3rInsufficientBond();
109 | unchecked {
110 | keeperBond[msg.sender] = bonded - amount;
111 | totalBonded -= amount;
112 | }
113 | if (!VEIL.transfer(msg.sender, amount)) revert Keep3rTransferFailed();
114 | emit Unbonded(msg.sender, amount, keeperBond[msg.sender]);
115 | }
116 |
117 | function worked(address keeper, uint256 amount) external onlyJob {
118 | if (amount == 0) revert Keep3rInvalidAmount();
119 | if (!isKeeper(keeper)) revert Keep3rNotActiveKeeper();
120 | if (availableCredits() < amount) revert Keep3rInsufficientCredits();
121 | if (!VEIL.transfer(keeper, amount)) revert Keep3rTransferFailed();
122 | emit Worked(msg.sender, keeper, amount);
123 | }
124 |
125 | function slash(address keeper, uint256 amount, address recipient) external onlyOwner {
126 | if (recipient == address(0)) revert Keep3rZeroAddress();
127 | if (amount == 0) revert Keep3rInvalidAmount();
128 | uint256 bonded = keeperBond[keeper];
129 | if (bonded < amount) revert Keep3rInsufficientBond();
130 | unchecked {
131 | keeperBond[keeper] = bonded - amount;
132 | totalBonded -= amount;
133 | }
134 | if (!VEIL.transfer(recipient, amount)) revert Keep3rTransferFailed();
135 | emit Slashed(keeper, recipient, amount);
136 | }
137 | }
138 |
VeilLiquidityIntentGateway.sol
EVM Intent Gateway (Liquidity)
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | /// @notice EVM-side intent gateway for VEIL UniV2 liquidity actions.
5 | /// Relayers consume submitted intents and execute them through the VEIL router.
6 | contract VeilLiquidityIntentGateway {
7 | uint8 public constant OP_CREATE_POOL = 0;
8 | uint8 public constant OP_ADD_LIQUIDITY = 1;
9 | uint8 public constant OP_REMOVE_LIQUIDITY = 2;
10 | uint8 public constant OP_SWAP_EXACT_IN = 3;
11 |
12 | uint8 public constant ASSET_VEIL = 0;
13 | uint8 public constant ASSET_VAI = 1;
14 |
15 | uint16 public constant MIN_POOL_FEE_BIPS = 1;
16 | uint16 public constant MAX_POOL_FEE_BIPS = 1000;
17 |
18 | enum IntentState {
19 | NONE,
20 | SUBMITTED,
21 | EXECUTED,
22 | CANCELLED
23 | }
24 |
25 | struct LiquidityIntent {
26 | address trader;
27 | uint8 operation;
28 | uint8 asset0;
29 | uint8 asset1;
30 | uint16 feeBips;
31 | uint64 amount0;
32 | uint64 amount1;
33 | uint64 minLP;
34 | uint64 lpAmount;
35 | uint64 minAmount0;
36 | uint64 minAmount1;
37 | uint64 amountIn;
38 | uint64 minAmountOut;
39 | uint64 nonce;
40 | IntentState state;
41 | }
42 |
43 | error Unauthorized();
44 | error InvalidAddress();
45 | error InvalidOperation(uint8 operation);
46 | error InvalidAsset(uint8 asset);
47 | error InvalidAssetPair(uint8 asset0, uint8 asset1);
48 | error InvalidAmount();
49 | error InvalidFeeBips(uint16 feeBips);
50 | error IntentAlreadyExists(bytes32 intentId);
51 | error IntentNotFound(bytes32 intentId);
52 | error IntentNotSubmitted(bytes32 intentId);
53 | error IntentNotOwned(bytes32 intentId, address expectedOwner, address sender);
54 |
55 | event OwnerTransferred(address indexed previousOwner, address indexed newOwner);
56 | event RelayExecutorSet(address indexed previousRelay, address indexed newRelay);
57 |
58 | event LiquidityIntentSubmitted(
59 | bytes32 indexed intentId,
60 | address indexed trader,
61 | uint8 indexed operation,
62 | uint8 asset0,
63 | uint8 asset1,
64 | uint16 feeBips,
65 | uint64 amount0,
66 | uint64 amount1,
67 | uint64 minLP,
68 | uint64 lpAmount,
69 | uint64 minAmount0,
70 | uint64 minAmount1,
71 | uint64 amountIn,
72 | uint64 minAmountOut,
73 | uint64 nonce
74 | );
75 | event LiquidityIntentExecuted(bytes32 indexed intentId, bytes32 indexed veilTxHash, address indexed executor);
76 | event LiquidityIntentCancelled(bytes32 indexed intentId, address indexed trader);
77 |
78 | address public owner;
79 | address public relayExecutor;
80 |
81 | mapping(address => uint64) public nonces;
82 | mapping(bytes32 => LiquidityIntent) private intents;
83 |
84 | modifier onlyOwner() {
85 | if (msg.sender != owner) {
86 | revert Unauthorized();
87 | }
88 | _;
89 | }
90 |
91 | modifier onlyRelay() {
92 | if (msg.sender != relayExecutor) {
93 | revert Unauthorized();
94 | }
95 | _;
96 | }
97 |
98 | constructor(address initialOwner, address initialRelayExecutor) {
99 | owner = initialOwner == address(0) ? msg.sender : initialOwner;
100 | relayExecutor = initialRelayExecutor;
101 | emit OwnerTransferred(address(0), owner);
102 | emit RelayExecutorSet(address(0), initialRelayExecutor);
103 | }
104 |
105 | function transferOwnership(address newOwner) external onlyOwner {
106 | if (newOwner == address(0)) {
107 | revert InvalidAddress();
108 | }
109 | emit OwnerTransferred(owner, newOwner);
110 | owner = newOwner;
111 | }
112 |
113 | function setRelayExecutor(address newRelayExecutor) external onlyOwner {
114 | emit RelayExecutorSet(relayExecutor, newRelayExecutor);
115 | relayExecutor = newRelayExecutor;
116 | }
117 |
118 | function submitCreatePoolIntent(uint8 asset0, uint8 asset1, uint16 feeBips) external returns (bytes32 intentId) {
119 | _validateAssetPair(asset0, asset1);
120 | if (feeBips < MIN_POOL_FEE_BIPS || feeBips > MAX_POOL_FEE_BIPS) {
121 | revert InvalidFeeBips(feeBips);
122 | }
123 | intentId = _storeIntent(OP_CREATE_POOL, asset0, asset1, feeBips, 0, 0, 0, 0, 0, 0, 0, 0);
124 | }
125 |
126 | function submitAddLiquidityIntent(
127 | uint8 asset0,
128 | uint8 asset1,
129 | uint64 amount0,
130 | uint64 amount1,
131 | uint64 minLP
132 | ) external returns (bytes32 intentId) {
133 | _validateAssetPair(asset0, asset1);
134 | if (amount0 == 0 || amount1 == 0) {
135 | revert InvalidAmount();
136 | }
137 | intentId = _storeIntent(OP_ADD_LIQUIDITY, asset0, asset1, 0, amount0, amount1, minLP, 0, 0, 0, 0, 0);
138 | }
139 |
140 | function submitRemoveLiquidityIntent(
141 | uint8 asset0,
142 | uint8 asset1,
143 | uint64 lpAmount,
144 | uint64 minAmount0,
145 | uint64 minAmount1
146 | ) external returns (bytes32 intentId) {
147 | _validateAssetPair(asset0, asset1);
148 | if (lpAmount == 0) {
149 | revert InvalidAmount();
150 | }
151 | intentId = _storeIntent(OP_REMOVE_LIQUIDITY, asset0, asset1, 0, 0, 0, 0, lpAmount, minAmount0, minAmount1, 0, 0);
152 | }
153 |
154 | function submitSwapExactInIntent(
155 | uint8 assetIn,
156 | uint8 assetOut,
157 | uint64 amountIn,
158 | uint64 minAmountOut
159 | ) external returns (bytes32 intentId) {
160 | _validateAssetPair(assetIn, assetOut);
161 | if (amountIn == 0) {
162 | revert InvalidAmount();
163 | }
164 | intentId = _storeIntent(OP_SWAP_EXACT_IN, assetIn, assetOut, 0, 0, 0, 0, 0, 0, 0, amountIn, minAmountOut);
165 | }
166 |
167 | function markIntentExecuted(bytes32 intentId, bytes32 veilTxHash) external onlyRelay {
168 | LiquidityIntent storage intent = intents[intentId];
169 | if (intent.state == IntentState.NONE) {
170 | revert IntentNotFound(intentId);
171 | }
172 | if (intent.state != IntentState.SUBMITTED) {
173 | revert IntentNotSubmitted(intentId);
174 | }
175 | intent.state = IntentState.EXECUTED;
176 | emit LiquidityIntentExecuted(intentId, veilTxHash, msg.sender);
177 | }
178 |
179 | function cancelIntent(bytes32 intentId) external {
180 | LiquidityIntent storage intent = intents[intentId];
181 | if (intent.state == IntentState.NONE) {
182 | revert IntentNotFound(intentId);
183 | }
184 | if (intent.trader != msg.sender) {
185 | revert IntentNotOwned(intentId, intent.trader, msg.sender);
186 | }
187 | if (intent.state != IntentState.SUBMITTED) {
188 | revert IntentNotSubmitted(intentId);
189 | }
190 | intent.state = IntentState.CANCELLED;
191 | emit LiquidityIntentCancelled(intentId, msg.sender);
192 | }
193 |
194 | function getIntent(bytes32 intentId) external view returns (LiquidityIntent memory) {
195 | LiquidityIntent memory intent = intents[intentId];
196 | if (intent.state == IntentState.NONE) {
197 | revert IntentNotFound(intentId);
198 | }
199 | return intent;
200 | }
201 |
202 | function _storeIntent(
203 | uint8 operation,
204 | uint8 asset0,
205 | uint8 asset1,
206 | uint16 feeBips,
207 | uint64 amount0,
208 | uint64 amount1,
209 | uint64 minLP,
210 | uint64 lpAmount,
211 | uint64 minAmount0,
212 | uint64 minAmount1,
213 | uint64 amountIn,
214 | uint64 minAmountOut
215 | ) internal returns (bytes32 intentId) {
216 | if (operation > OP_SWAP_EXACT_IN) {
217 | revert InvalidOperation(operation);
218 | }
219 |
220 | uint64 nonce = nonces[msg.sender];
221 | nonces[msg.sender] = nonce + 1;
222 | intentId = keccak256(
223 | abi.encode(
224 | block.chainid,
225 | address(this),
226 | msg.sender,
227 | operation,
228 | asset0,
229 | asset1,
230 | feeBips,
231 | amount0,
232 | amount1,
233 | minLP,
234 | lpAmount,
235 | minAmount0,
236 | minAmount1,
237 | amountIn,
238 | minAmountOut,
239 | nonce
240 | )
241 | );
242 |
243 | if (intents[intentId].state != IntentState.NONE) {
244 | revert IntentAlreadyExists(intentId);
245 | }
246 |
247 | intents[intentId] = LiquidityIntent({
248 | trader: msg.sender,
249 | operation: operation,
250 | asset0: asset0,
251 | asset1: asset1,
252 | feeBips: feeBips,
253 | amount0: amount0,
254 | amount1: amount1,
255 | minLP: minLP,
256 | lpAmount: lpAmount,
257 | minAmount0: minAmount0,
258 | minAmount1: minAmount1,
259 | amountIn: amountIn,
260 | minAmountOut: minAmountOut,
261 | nonce: nonce,
262 | state: IntentState.SUBMITTED
263 | });
264 |
265 | emit LiquidityIntentSubmitted(
266 | intentId,
267 | msg.sender,
268 | operation,
269 | asset0,
270 | asset1,
271 | feeBips,
272 | amount0,
273 | amount1,
274 | minLP,
275 | lpAmount,
276 | minAmount0,
277 | minAmount1,
278 | amountIn,
279 | minAmountOut,
280 | nonce
281 | );
282 | }
283 |
284 | function _validateAssetPair(uint8 asset0, uint8 asset1) internal pure {
285 | if (!_isSupportedAsset(asset0)) {
286 | revert InvalidAsset(asset0);
287 | }
288 | if (!_isSupportedAsset(asset1)) {
289 | revert InvalidAsset(asset1);
290 | }
291 | if (asset0 == asset1) {
292 | revert InvalidAssetPair(asset0, asset1);
293 | }
294 | }
295 |
296 | function _isSupportedAsset(uint8 asset) internal pure returns (bool) {
297 | return asset == ASSET_VEIL || asset == ASSET_VAI;
298 | }
299 | }
300 |
VeilOrderIntentGateway.sol
EVM Intent Gateway (Order)
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | /// @notice Lightweight EVM entrypoint that captures user order intents and
5 | /// emits deterministic events for the VEIL relayer.
6 | contract VeilOrderIntentGateway {
7 | uint8 public constant SIDE_BUY = 0;
8 | uint8 public constant SIDE_SELL = 1;
9 | uint8 public constant OUTCOME_YES = 0;
10 | uint8 public constant OUTCOME_NO = 1;
11 | uint8 public constant MARKET_TYPE_VEIL_NATIVE = 0;
12 | uint8 public constant MARKET_TYPE_POLYGON_NATIVE = 1;
13 | uint16 public constant POLYGON_ROUTING_FEE_BPS = 3; // 0.03%
14 |
15 | enum IntentState {
16 | NONE,
17 | SUBMITTED,
18 | EXECUTED,
19 | CANCELLED
20 | }
21 |
22 | struct Intent {
23 | address trader;
24 | bytes32 marketKey;
25 | uint64 amountUsdE6;
26 | uint16 routingFeeBps;
27 | uint8 side;
28 | uint8 outcome;
29 | uint8 marketType;
30 | uint64 nonce;
31 | IntentState state;
32 | }
33 |
34 | error Unauthorized();
35 | error InvalidAddress();
36 | error InvalidSide(uint8 side);
37 | error InvalidOutcome(uint8 outcome);
38 | error InvalidMarketType(uint8 marketType);
39 | error InvalidAmount();
40 | error InvalidRoutingFee(uint16 provided, uint16 requiredFloor, uint8 marketType);
41 | error IntentAlreadyExists(bytes32 intentId);
42 | error IntentNotFound(bytes32 intentId);
43 | error IntentNotSubmitted(bytes32 intentId);
44 | error IntentNotOwned(bytes32 intentId, address expectedOwner, address sender);
45 |
46 | event OwnerTransferred(address indexed previousOwner, address indexed newOwner);
47 | event RelayExecutorSet(address indexed previousRelay, address indexed newRelay);
48 | event IntentSubmitted(
49 | bytes32 indexed intentId,
50 | address indexed trader,
51 | bytes32 indexed marketKey,
52 | uint8 side,
53 | uint8 outcome,
54 | uint64 amountUsdE6,
55 | uint8 marketType,
56 | uint16 routingFeeBps,
57 | uint64 nonce
58 | );
59 | event IntentExecuted(bytes32 indexed intentId, bytes32 indexed veilTxHash, address indexed executor);
60 | event IntentCancelled(bytes32 indexed intentId, address indexed trader);
61 |
62 | address public owner;
63 | address public relayExecutor;
64 |
65 | mapping(address => uint64) public nonces;
66 | mapping(bytes32 => Intent) private intents;
67 |
68 | modifier onlyOwner() {
69 | if (msg.sender != owner) {
70 | revert Unauthorized();
71 | }
72 | _;
73 | }
74 |
75 | modifier onlyRelay() {
76 | if (msg.sender != relayExecutor) {
77 | revert Unauthorized();
78 | }
79 | _;
80 | }
81 |
82 | constructor(address initialOwner, address initialRelayExecutor) {
83 | owner = initialOwner == address(0) ? msg.sender : initialOwner;
84 | relayExecutor = initialRelayExecutor;
85 | emit OwnerTransferred(address(0), owner);
86 | emit RelayExecutorSet(address(0), initialRelayExecutor);
87 | }
88 |
89 | function transferOwnership(address newOwner) external onlyOwner {
90 | if (newOwner == address(0)) {
91 | revert InvalidAddress();
92 | }
93 | emit OwnerTransferred(owner, newOwner);
94 | owner = newOwner;
95 | }
96 |
97 | function setRelayExecutor(address newRelayExecutor) external onlyOwner {
98 | emit RelayExecutorSet(relayExecutor, newRelayExecutor);
99 | relayExecutor = newRelayExecutor;
100 | }
101 |
102 | function submitIntent(
103 | bytes32 marketKey,
104 | uint8 side,
105 | uint8 outcome,
106 | uint64 amountUsdE6,
107 | uint8 marketType,
108 | uint16 routingFeeBps
109 | ) external returns (bytes32 intentId) {
110 | if (side > SIDE_SELL) {
111 | revert InvalidSide(side);
112 | }
113 | if (outcome > OUTCOME_NO) {
114 | revert InvalidOutcome(outcome);
115 | }
116 | if (marketType > MARKET_TYPE_POLYGON_NATIVE) {
117 | revert InvalidMarketType(marketType);
118 | }
119 | if (amountUsdE6 == 0) {
120 | revert InvalidAmount();
121 | }
122 |
123 | uint16 normalizedRoutingFeeBps = normalizeRoutingFee(marketType, routingFeeBps);
124 | uint64 nonce = nonces[msg.sender];
125 | nonces[msg.sender] = nonce + 1;
126 |
127 | intentId = keccak256(
128 | abi.encode(
129 | block.chainid,
130 | address(this),
131 | msg.sender,
132 | marketKey,
133 | side,
134 | outcome,
135 | amountUsdE6,
136 | marketType,
137 | normalizedRoutingFeeBps,
138 | nonce
139 | )
140 | );
141 |
142 | if (intents[intentId].state != IntentState.NONE) {
143 | revert IntentAlreadyExists(intentId);
144 | }
145 |
146 | intents[intentId] = Intent({
147 | trader: msg.sender,
148 | marketKey: marketKey,
149 | amountUsdE6: amountUsdE6,
150 | routingFeeBps: normalizedRoutingFeeBps,
151 | side: side,
152 | outcome: outcome,
153 | marketType: marketType,
154 | nonce: nonce,
155 | state: IntentState.SUBMITTED
156 | });
157 |
158 | emit IntentSubmitted(
159 | intentId,
160 | msg.sender,
161 | marketKey,
162 | side,
163 | outcome,
164 | amountUsdE6,
165 | marketType,
166 | normalizedRoutingFeeBps,
167 | nonce
168 | );
169 | }
170 |
171 | function markIntentExecuted(bytes32 intentId, bytes32 veilTxHash) external onlyRelay {
172 | Intent storage intent = intents[intentId];
173 | if (intent.state == IntentState.NONE) {
174 | revert IntentNotFound(intentId);
175 | }
176 | if (intent.state != IntentState.SUBMITTED) {
177 | revert IntentNotSubmitted(intentId);
178 | }
179 | intent.state = IntentState.EXECUTED;
180 | emit IntentExecuted(intentId, veilTxHash, msg.sender);
181 | }
182 |
183 | function cancelIntent(bytes32 intentId) external {
184 | Intent storage intent = intents[intentId];
185 | if (intent.state == IntentState.NONE) {
186 | revert IntentNotFound(intentId);
187 | }
188 | if (intent.trader != msg.sender) {
189 | revert IntentNotOwned(intentId, intent.trader, msg.sender);
190 | }
191 | if (intent.state != IntentState.SUBMITTED) {
192 | revert IntentNotSubmitted(intentId);
193 | }
194 | intent.state = IntentState.CANCELLED;
195 | emit IntentCancelled(intentId, msg.sender);
196 | }
197 |
198 | function getIntent(bytes32 intentId) external view returns (Intent memory) {
199 | Intent memory intent = intents[intentId];
200 | if (intent.state == IntentState.NONE) {
201 | revert IntentNotFound(intentId);
202 | }
203 | return intent;
204 | }
205 |
206 | function normalizeRoutingFee(uint8 marketType, uint16 requestedFeeBps) public pure returns (uint16) {
207 | if (marketType == MARKET_TYPE_POLYGON_NATIVE) {
208 | if (requestedFeeBps == 0) {
209 | return POLYGON_ROUTING_FEE_BPS;
210 | }
211 | if (requestedFeeBps < POLYGON_ROUTING_FEE_BPS) {
212 | revert InvalidRoutingFee(requestedFeeBps, POLYGON_ROUTING_FEE_BPS, marketType);
213 | }
214 | return requestedFeeBps;
215 | }
216 |
217 | if (requestedFeeBps != 0) {
218 | revert InvalidRoutingFee(requestedFeeBps, 0, marketType);
219 | }
220 | return 0;
221 | }
222 | }
223 |
VeilTreasury.sol
EVM Treasury
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | interface IERC20LikeTreasury {
5 | function transfer(address to, uint256 value) external returns (bool);
6 | function transferFrom(address from, address to, uint256 value) external returns (bool);
7 | }
8 |
9 | interface IVeilVAITreasury {
10 | function mint(address to, uint256 amount) external;
11 | function burnFrom(address from, uint256 amount) external;
12 | }
13 |
14 | /// @notice Companion EVM treasury for VEIL/wVEIL + VAI operations.
15 | /// @dev Owner-controlled for now; designed for fast local recovery workflows.
16 | contract VeilTreasury {
17 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
18 | event Keep3rSet(address indexed previousKeep3r, address indexed nextKeep3r);
19 | event VeilDeposited(address indexed from, uint256 amount);
20 | event Keep3rFunded(address indexed keep3r, uint256 amount);
21 | event VAIMinted(address indexed to, uint256 amount);
22 | event VAIBurned(address indexed from, uint256 amount);
23 | event TokenWithdrawn(address indexed token, address indexed to, uint256 amount);
24 |
25 | error TreasuryZeroAddress();
26 | error TreasuryOnlyOwner();
27 | error TreasuryKeep3rUnset();
28 | error TreasuryTokenTransferFailed();
29 |
30 | address public owner;
31 | address public keep3r;
32 | IERC20LikeTreasury public immutable VEIL;
33 | IVeilVAITreasury public immutable VAI;
34 |
35 | modifier onlyOwner() {
36 | if (msg.sender != owner) revert TreasuryOnlyOwner();
37 | _;
38 | }
39 |
40 | constructor(address veilToken_, address vaiToken_, address owner_) {
41 | if (veilToken_ == address(0) || vaiToken_ == address(0) || owner_ == address(0)) {
42 | revert TreasuryZeroAddress();
43 | }
44 | VEIL = IERC20LikeTreasury(veilToken_);
45 | VAI = IVeilVAITreasury(vaiToken_);
46 | owner = owner_;
47 | emit OwnershipTransferred(address(0), owner_);
48 | }
49 |
50 | function transferOwnership(address nextOwner) external onlyOwner {
51 | if (nextOwner == address(0)) revert TreasuryZeroAddress();
52 | emit OwnershipTransferred(owner, nextOwner);
53 | owner = nextOwner;
54 | }
55 |
56 | function setKeep3r(address nextKeep3r) external onlyOwner {
57 | if (nextKeep3r == address(0)) revert TreasuryZeroAddress();
58 | emit Keep3rSet(keep3r, nextKeep3r);
59 | keep3r = nextKeep3r;
60 | }
61 |
62 | function depositVeil(uint256 amount) external {
63 | if (!VEIL.transferFrom(msg.sender, address(this), amount)) {
64 | revert TreasuryTokenTransferFailed();
65 | }
66 | emit VeilDeposited(msg.sender, amount);
67 | }
68 |
69 | function fundKeep3r(uint256 amount) external onlyOwner {
70 | address target = keep3r;
71 | if (target == address(0)) revert TreasuryKeep3rUnset();
72 | if (!VEIL.transfer(target, amount)) revert TreasuryTokenTransferFailed();
73 | emit Keep3rFunded(target, amount);
74 | }
75 |
76 | function mintVAI(address to, uint256 amount) external onlyOwner {
77 | VAI.mint(to, amount);
78 | emit VAIMinted(to, amount);
79 | }
80 |
81 | function burnVAIFrom(address from, uint256 amount) external onlyOwner {
82 | VAI.burnFrom(from, amount);
83 | emit VAIBurned(from, amount);
84 | }
85 |
86 | function withdrawToken(address token, address to, uint256 amount) external onlyOwner {
87 | if (token == address(0) || to == address(0)) revert TreasuryZeroAddress();
88 | if (!IERC20LikeTreasury(token).transfer(to, amount)) {
89 | revert TreasuryTokenTransferFailed();
90 | }
91 | emit TokenWithdrawn(token, to, amount);
92 | }
93 | }
94 |
VeilUniV2Dex.sol
EVM UniV2 LP/DEX
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | interface IERC20MiniUniV2 {
5 | function totalSupply() external view returns (uint256);
6 | function balanceOf(address account) external view returns (uint256);
7 | function allowance(address owner, address spender) external view returns (uint256);
8 | function approve(address spender, uint256 amount) external returns (bool);
9 | function transfer(address to, uint256 amount) external returns (bool);
10 | function transferFrom(address from, address to, uint256 amount) external returns (bool);
11 | }
12 |
13 | library VeilUniV2Math {
14 | function min(uint256 a, uint256 b) internal pure returns (uint256) {
15 | return a < b ? a : b;
16 | }
17 |
18 | function sqrt(uint256 y) internal pure returns (uint256 z) {
19 | if (y > 3) {
20 | z = y;
21 | uint256 x = y / 2 + 1;
22 | while (x < z) {
23 | z = x;
24 | x = (y / x + x) / 2;
25 | }
26 | } else if (y != 0) {
27 | z = 1;
28 | }
29 | }
30 | }
31 |
32 | /// @notice Minimal Uniswap V2-style pair for VEIL companion EVM rails.
33 | contract VeilUniV2Pair {
34 | string public constant name = "VEIL LP";
35 | string public constant symbol = "VLP";
36 | uint8 public constant decimals = 18;
37 | uint256 public constant MINIMUM_LIQUIDITY = 1_000;
38 |
39 | address public immutable factory;
40 | address public immutable token0;
41 | address public immutable token1;
42 |
43 | uint112 private reserve0;
44 | uint112 private reserve1;
45 | uint32 private blockTimestampLast;
46 |
47 | uint256 public totalSupply;
48 | mapping(address => uint256) public balanceOf;
49 | mapping(address => mapping(address => uint256)) public allowance;
50 |
51 | event Approval(address indexed owner, address indexed spender, uint256 value);
52 | event Transfer(address indexed from, address indexed to, uint256 value);
53 | event Mint(address indexed sender, uint256 amount0, uint256 amount1);
54 | event Burn(address indexed sender, uint256 amount0, uint256 amount1, address indexed to);
55 | event Swap(
56 | address indexed sender,
57 | uint256 amount0In,
58 | uint256 amount1In,
59 | uint256 amount0Out,
60 | uint256 amount1Out,
61 | address indexed to
62 | );
63 | event Sync(uint112 reserve0, uint112 reserve1);
64 |
65 | error UniV2BadConfig();
66 | error UniV2InsufficientLiquidityMinted();
67 | error UniV2InsufficientLiquidityBurned();
68 | error UniV2InsufficientOutputAmount();
69 | error UniV2InsufficientLiquidity();
70 | error UniV2InvalidTo();
71 | error UniV2TransferFailed();
72 | error UniV2KInvariant();
73 |
74 | constructor(address token0_, address token1_) {
75 | if (token0_ == token1_ || token0_ == address(0) || token1_ == address(0)) {
76 | revert UniV2BadConfig();
77 | }
78 | factory = msg.sender;
79 | token0 = token0_;
80 | token1 = token1_;
81 | }
82 |
83 | function getReserves() external view returns (uint112, uint112, uint32) {
84 | return (reserve0, reserve1, blockTimestampLast);
85 | }
86 |
87 | function approve(address spender, uint256 value) external returns (bool) {
88 | allowance[msg.sender][spender] = value;
89 | emit Approval(msg.sender, spender, value);
90 | return true;
91 | }
92 |
93 | function transfer(address to, uint256 value) external returns (bool) {
94 | return transferFrom(msg.sender, to, value);
95 | }
96 |
97 | function transferFrom(address from, address to, uint256 value) public returns (bool) {
98 | if (to == address(0)) revert UniV2InvalidTo();
99 | if (from != msg.sender) {
100 | uint256 allowed = allowance[from][msg.sender];
101 | if (allowed != type(uint256).max) {
102 | require(allowed >= value, "UniV2/insufficient-allowance");
103 | unchecked {
104 | allowance[from][msg.sender] = allowed - value;
105 | }
106 | emit Approval(from, msg.sender, allowance[from][msg.sender]);
107 | }
108 | }
109 | require(balanceOf[from] >= value, "UniV2/insufficient-balance");
110 | unchecked {
111 | balanceOf[from] -= value;
112 | balanceOf[to] += value;
113 | }
114 | emit Transfer(from, to, value);
115 | return true;
116 | }
117 |
118 | function mint(address to) external returns (uint256 liquidity) {
119 | (uint112 r0, uint112 r1,) = (reserve0, reserve1, blockTimestampLast);
120 | uint256 balance0 = IERC20MiniUniV2(token0).balanceOf(address(this));
121 | uint256 balance1 = IERC20MiniUniV2(token1).balanceOf(address(this));
122 | uint256 amount0 = balance0 - r0;
123 | uint256 amount1 = balance1 - r1;
124 |
125 | uint256 _totalSupply = totalSupply;
126 | if (_totalSupply == 0) {
127 | liquidity = VeilUniV2Math.sqrt(amount0 * amount1) - MINIMUM_LIQUIDITY;
128 | _mint(address(0), MINIMUM_LIQUIDITY);
129 | } else {
130 | liquidity = VeilUniV2Math.min((amount0 * _totalSupply) / r0, (amount1 * _totalSupply) / r1);
131 | }
132 |
133 | if (liquidity == 0) revert UniV2InsufficientLiquidityMinted();
134 | _mint(to, liquidity);
135 | _update(balance0, balance1);
136 | emit Mint(msg.sender, amount0, amount1);
137 | }
138 |
139 | function burn(address to) external returns (uint256 amount0, uint256 amount1) {
140 | if (to == address(0)) revert UniV2InvalidTo();
141 | address _token0 = token0;
142 | address _token1 = token1;
143 | uint256 balance0 = IERC20MiniUniV2(_token0).balanceOf(address(this));
144 | uint256 balance1 = IERC20MiniUniV2(_token1).balanceOf(address(this));
145 | uint256 liquidity = balanceOf[address(this)];
146 |
147 | uint256 _totalSupply = totalSupply;
148 | amount0 = (liquidity * balance0) / _totalSupply;
149 | amount1 = (liquidity * balance1) / _totalSupply;
150 | if (amount0 == 0 || amount1 == 0) revert UniV2InsufficientLiquidityBurned();
151 |
152 | _burn(address(this), liquidity);
153 | _safeTransfer(_token0, to, amount0);
154 | _safeTransfer(_token1, to, amount1);
155 |
156 | balance0 = IERC20MiniUniV2(_token0).balanceOf(address(this));
157 | balance1 = IERC20MiniUniV2(_token1).balanceOf(address(this));
158 |
159 | _update(balance0, balance1);
160 | emit Burn(msg.sender, amount0, amount1, to);
161 | }
162 |
163 | function swap(uint256 amount0Out, uint256 amount1Out, address to) external {
164 | if (amount0Out == 0 && amount1Out == 0) revert UniV2InsufficientOutputAmount();
165 | (uint112 r0, uint112 r1,) = (reserve0, reserve1, blockTimestampLast);
166 | if (amount0Out >= r0 || amount1Out >= r1) revert UniV2InsufficientLiquidity();
167 | if (to == token0 || to == token1 || to == address(0)) revert UniV2InvalidTo();
168 |
169 | if (amount0Out > 0) _safeTransfer(token0, to, amount0Out);
170 | if (amount1Out > 0) _safeTransfer(token1, to, amount1Out);
171 |
172 | uint256 balance0 = IERC20MiniUniV2(token0).balanceOf(address(this));
173 | uint256 balance1 = IERC20MiniUniV2(token1).balanceOf(address(this));
174 | uint256 amount0In = balance0 > (r0 - amount0Out) ? balance0 - (r0 - amount0Out) : 0;
175 | uint256 amount1In = balance1 > (r1 - amount1Out) ? balance1 - (r1 - amount1Out) : 0;
176 | if (amount0In == 0 && amount1In == 0) revert UniV2InsufficientOutputAmount();
177 |
178 | // 30 bps fee: x * 997 / 1000.
179 | uint256 balance0Adjusted = (balance0 * 1000) - (amount0In * 3);
180 | uint256 balance1Adjusted = (balance1 * 1000) - (amount1In * 3);
181 | if (balance0Adjusted * balance1Adjusted < uint256(r0) * uint256(r1) * 1_000_000) {
182 | revert UniV2KInvariant();
183 | }
184 |
185 | _update(balance0, balance1);
186 | emit Swap(msg.sender, amount0In, amount1In, amount0Out, amount1Out, to);
187 | }
188 |
189 | function sync() external {
190 | _update(
191 | IERC20MiniUniV2(token0).balanceOf(address(this)),
192 | IERC20MiniUniV2(token1).balanceOf(address(this))
193 | );
194 | }
195 |
196 | function _safeTransfer(address token, address to, uint256 value) private {
197 | (bool ok, bytes memory data) =
198 | token.call(abi.encodeWithSelector(IERC20MiniUniV2.transfer.selector, to, value));
199 | if (!ok || (data.length != 0 && !abi.decode(data, (bool)))) {
200 | revert UniV2TransferFailed();
201 | }
202 | }
203 |
204 | function _update(uint256 balance0, uint256 balance1) private {
205 | reserve0 = uint112(balance0);
206 | reserve1 = uint112(balance1);
207 | blockTimestampLast = uint32(block.timestamp);
208 | emit Sync(reserve0, reserve1);
209 | }
210 |
211 | function _mint(address to, uint256 value) private {
212 | totalSupply += value;
213 | unchecked {
214 | balanceOf[to] += value;
215 | }
216 | emit Transfer(address(0), to, value);
217 | }
218 |
219 | function _burn(address from, uint256 value) private {
220 | unchecked {
221 | balanceOf[from] -= value;
222 | totalSupply -= value;
223 | }
224 | emit Transfer(from, address(0), value);
225 | }
226 | }
227 |
228 | contract VeilUniV2Factory {
229 | mapping(address => mapping(address => address)) public getPair;
230 | address[] public allPairs;
231 |
232 | event PairCreated(address indexed token0, address indexed token1, address pair, uint256 totalPairs);
233 |
234 | error UniV2IdenticalAddresses();
235 | error UniV2ZeroAddress();
236 | error UniV2PairExists();
237 |
238 | function allPairsLength() external view returns (uint256) {
239 | return allPairs.length;
240 | }
241 |
242 | function createPair(address tokenA, address tokenB) external returns (address pair) {
243 | if (tokenA == tokenB) revert UniV2IdenticalAddresses();
244 | (address token0, address token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
245 | if (token0 == address(0)) revert UniV2ZeroAddress();
246 | if (getPair[token0][token1] != address(0)) revert UniV2PairExists();
247 |
248 | pair = address(new VeilUniV2Pair(token0, token1));
249 | getPair[token0][token1] = pair;
250 | getPair[token1][token0] = pair;
251 | allPairs.push(pair);
252 |
253 | emit PairCreated(token0, token1, pair, allPairs.length);
254 | }
255 | }
256 |
257 | contract VeilUniV2Router {
258 | address public immutable factory;
259 |
260 | error UniV2InvalidPath();
261 | error UniV2PairMissing();
262 | error UniV2InsufficientA();
263 | error UniV2InsufficientB();
264 | error UniV2InsufficientOut();
265 | error UniV2TransferFailed();
266 |
267 | constructor(address factory_) {
268 | require(factory_ != address(0), "UniV2Router/bad-factory");
269 | factory = factory_;
270 | }
271 |
272 | function quote(uint256 amountA, uint256 reserveA, uint256 reserveB) public pure returns (uint256 amountB) {
273 | require(amountA > 0, "UniV2Router/insufficient-amount");
274 | require(reserveA > 0 && reserveB > 0, "UniV2Router/insufficient-liquidity");
275 | amountB = (amountA * reserveB) / reserveA;
276 | }
277 |
278 | function getAmountOut(uint256 amountIn, uint256 reserveIn, uint256 reserveOut)
279 | public
280 | pure
281 | returns (uint256 amountOut)
282 | {
283 | require(amountIn > 0, "UniV2Router/insufficient-input");
284 | require(reserveIn > 0 && reserveOut > 0, "UniV2Router/insufficient-liquidity");
285 | uint256 amountInWithFee = amountIn * 997;
286 | amountOut = (amountInWithFee * reserveOut) / (reserveIn * 1000 + amountInWithFee);
287 | }
288 |
289 | function getAmountsOut(uint256 amountIn, address[] memory path) public view returns (uint256[] memory amounts) {
290 | if (path.length < 2) revert UniV2InvalidPath();
291 | amounts = new uint256[](path.length);
292 | amounts[0] = amountIn;
293 | for (uint256 i = 0; i < path.length - 1; i++) {
294 | (uint256 reserveIn, uint256 reserveOut) = getReserves(path[i], path[i + 1]);
295 | amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
296 | }
297 | }
298 |
299 | function getReserves(address tokenA, address tokenB) public view returns (uint256 reserveA, uint256 reserveB) {
300 | address pair = VeilUniV2Factory(factory).getPair(tokenA, tokenB);
301 | if (pair == address(0)) revert UniV2PairMissing();
302 | (address token0,) = sortTokens(tokenA, tokenB);
303 | (uint112 reserve0, uint112 reserve1,) = VeilUniV2Pair(pair).getReserves();
304 | (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
305 | }
306 |
307 | function addLiquidity(
308 | address tokenA,
309 | address tokenB,
310 | uint256 amountADesired,
311 | uint256 amountBDesired,
312 | uint256 amountAMin,
313 | uint256 amountBMin,
314 | address to
315 | ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity) {
316 | address pair = VeilUniV2Factory(factory).getPair(tokenA, tokenB);
317 | if (pair == address(0)) {
318 | pair = VeilUniV2Factory(factory).createPair(tokenA, tokenB);
319 | }
320 |
321 | (uint256 reserveA, uint256 reserveB) = _tryGetReserves(tokenA, tokenB);
322 | if (reserveA == 0 && reserveB == 0) {
323 | (amountA, amountB) = (amountADesired, amountBDesired);
324 | } else {
325 | uint256 amountBOptimal = quote(amountADesired, reserveA, reserveB);
326 | if (amountBOptimal <= amountBDesired) {
327 | if (amountBOptimal < amountBMin) revert UniV2InsufficientB();
328 | (amountA, amountB) = (amountADesired, amountBOptimal);
329 | } else {
330 | uint256 amountAOptimal = quote(amountBDesired, reserveB, reserveA);
331 | if (amountAOptimal < amountAMin) revert UniV2InsufficientA();
332 | (amountA, amountB) = (amountAOptimal, amountBDesired);
333 | }
334 | }
335 |
336 | _safeTransferFrom(tokenA, msg.sender, pair, amountA);
337 | _safeTransferFrom(tokenB, msg.sender, pair, amountB);
338 | liquidity = VeilUniV2Pair(pair).mint(to);
339 | }
340 |
341 | function removeLiquidity(
342 | address tokenA,
343 | address tokenB,
344 | uint256 liquidity,
345 | uint256 amountAMin,
346 | uint256 amountBMin,
347 | address to
348 | ) external returns (uint256 amountA, uint256 amountB) {
349 | address pair = VeilUniV2Factory(factory).getPair(tokenA, tokenB);
350 | if (pair == address(0)) revert UniV2PairMissing();
351 | _safeTransferFrom(pair, msg.sender, pair, liquidity);
352 | (uint256 amount0, uint256 amount1) = VeilUniV2Pair(pair).burn(to);
353 | (address token0,) = sortTokens(tokenA, tokenB);
354 | (amountA, amountB) = tokenA == token0 ? (amount0, amount1) : (amount1, amount0);
355 | if (amountA < amountAMin) revert UniV2InsufficientA();
356 | if (amountB < amountBMin) revert UniV2InsufficientB();
357 | }
358 |
359 | function swapExactTokensForTokens(
360 | uint256 amountIn,
361 | uint256 amountOutMin,
362 | address[] calldata path,
363 | address to
364 | ) external returns (uint256[] memory amounts) {
365 | amounts = getAmountsOut(amountIn, path);
366 | if (amounts[amounts.length - 1] < amountOutMin) revert UniV2InsufficientOut();
367 | address firstPair = VeilUniV2Factory(factory).getPair(path[0], path[1]);
368 | if (firstPair == address(0)) revert UniV2PairMissing();
369 | _safeTransferFrom(path[0], msg.sender, firstPair, amounts[0]);
370 | _swap(amounts, path, to);
371 | }
372 |
373 | function _swap(uint256[] memory amounts, address[] calldata path, address to_) internal {
374 | for (uint256 i = 0; i < path.length - 1; i++) {
375 | (address input, address output) = (path[i], path[i + 1]);
376 | address pair = VeilUniV2Factory(factory).getPair(input, output);
377 | if (pair == address(0)) revert UniV2PairMissing();
378 | (address token0,) = sortTokens(input, output);
379 | uint256 amountOut = amounts[i + 1];
380 | (uint256 amount0Out, uint256 amount1Out) =
381 | input == token0 ? (uint256(0), amountOut) : (amountOut, uint256(0));
382 | address to = i < path.length - 2
383 | ? VeilUniV2Factory(factory).getPair(output, path[i + 2])
384 | : to_;
385 | VeilUniV2Pair(pair).swap(amount0Out, amount1Out, to);
386 | }
387 | }
388 |
389 | function sortTokens(address tokenA, address tokenB) public pure returns (address token0, address token1) {
390 | require(tokenA != tokenB, "UniV2Router/identical");
391 | (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA);
392 | require(token0 != address(0), "UniV2Router/zero");
393 | }
394 |
395 | function _tryGetReserves(address tokenA, address tokenB)
396 | internal
397 | view
398 | returns (uint256 reserveA, uint256 reserveB)
399 | {
400 | address pair = VeilUniV2Factory(factory).getPair(tokenA, tokenB);
401 | if (pair == address(0)) return (0, 0);
402 | (address token0,) = sortTokens(tokenA, tokenB);
403 | (uint112 reserve0, uint112 reserve1,) = VeilUniV2Pair(pair).getReserves();
404 | (reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
405 | }
406 |
407 | function _safeTransferFrom(address token, address from, address to, uint256 value) private {
408 | (bool ok, bytes memory data) =
409 | token.call(abi.encodeWithSelector(IERC20MiniUniV2.transferFrom.selector, from, to, value));
410 | if (!ok || (data.length != 0 && !abi.decode(data, (bool)))) {
411 | revert UniV2TransferFailed();
412 | }
413 | }
414 | }
415 |
VeilVAI.sol
EVM VAI
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | /// @notice Minimal VAI token for companion EVM rails.
5 | /// @dev Owner sets minter (treasury); minter mints, holders can burn.
6 | contract VeilVAI {
7 | string public constant name = "VEIL USD";
8 | string public constant symbol = "VAI";
9 | uint8 public constant decimals = 18;
10 |
11 | event Transfer(address indexed from, address indexed to, uint256 value);
12 | event Approval(address indexed owner, address indexed spender, uint256 value);
13 | event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
14 | event MinterSet(address indexed previousMinter, address indexed nextMinter);
15 |
16 | error VAIZeroAddress();
17 | error VAIOnlyOwner();
18 | error VAIOnlyMinter();
19 | error VAIInsufficientBalance();
20 | error VAIInsufficientAllowance();
21 |
22 | address public owner;
23 | address public minter;
24 |
25 | uint256 public totalSupply;
26 | mapping(address => uint256) public balanceOf;
27 | mapping(address => mapping(address => uint256)) public allowance;
28 |
29 | modifier onlyOwner() {
30 | if (msg.sender != owner) revert VAIOnlyOwner();
31 | _;
32 | }
33 |
34 | modifier onlyMinter() {
35 | if (msg.sender != minter) revert VAIOnlyMinter();
36 | _;
37 | }
38 |
39 | constructor(
40 | address owner_,
41 | address minter_,
42 | address initialRecipient_,
43 | uint256 initialSupply_
44 | ) {
45 | if (owner_ == address(0) || minter_ == address(0)) revert VAIZeroAddress();
46 | owner = owner_;
47 | minter = minter_;
48 | emit OwnershipTransferred(address(0), owner_);
49 |
50 | if (initialSupply_ > 0) {
51 | address recipient = initialRecipient_ == address(0) ? owner_ : initialRecipient_;
52 | _mint(recipient, initialSupply_);
53 | }
54 | }
55 |
56 | function transferOwnership(address nextOwner) external onlyOwner {
57 | if (nextOwner == address(0)) revert VAIZeroAddress();
58 | emit OwnershipTransferred(owner, nextOwner);
59 | owner = nextOwner;
60 | }
61 |
62 | function setMinter(address nextMinter) external onlyOwner {
63 | if (nextMinter == address(0)) revert VAIZeroAddress();
64 | emit MinterSet(minter, nextMinter);
65 | minter = nextMinter;
66 | }
67 |
68 | function approve(address spender, uint256 amount) external returns (bool) {
69 | allowance[msg.sender][spender] = amount;
70 | emit Approval(msg.sender, spender, amount);
71 | return true;
72 | }
73 |
74 | function transfer(address to, uint256 amount) external returns (bool) {
75 | _transfer(msg.sender, to, amount);
76 | return true;
77 | }
78 |
79 | function transferFrom(address from, address to, uint256 amount) external returns (bool) {
80 | if (from != msg.sender) {
81 | uint256 allowed = allowance[from][msg.sender];
82 | if (allowed != type(uint256).max) {
83 | if (allowed < amount) revert VAIInsufficientAllowance();
84 | unchecked {
85 | allowance[from][msg.sender] = allowed - amount;
86 | }
87 | emit Approval(from, msg.sender, allowance[from][msg.sender]);
88 | }
89 | }
90 | _transfer(from, to, amount);
91 | return true;
92 | }
93 |
94 | function mint(address to, uint256 amount) external onlyMinter {
95 | _mint(to, amount);
96 | }
97 |
98 | function burn(uint256 amount) external {
99 | _burn(msg.sender, amount);
100 | }
101 |
102 | function burnFrom(address from, uint256 amount) external {
103 | if (from != msg.sender) {
104 | uint256 allowed = allowance[from][msg.sender];
105 | if (allowed != type(uint256).max) {
106 | if (allowed < amount) revert VAIInsufficientAllowance();
107 | unchecked {
108 | allowance[from][msg.sender] = allowed - amount;
109 | }
110 | emit Approval(from, msg.sender, allowance[from][msg.sender]);
111 | }
112 | }
113 | _burn(from, amount);
114 | }
115 |
116 | function _transfer(address from, address to, uint256 amount) internal {
117 | if (to == address(0)) revert VAIZeroAddress();
118 | uint256 fromBal = balanceOf[from];
119 | if (fromBal < amount) revert VAIInsufficientBalance();
120 | unchecked {
121 | balanceOf[from] = fromBal - amount;
122 | balanceOf[to] += amount;
123 | }
124 | emit Transfer(from, to, amount);
125 | }
126 |
127 | function _mint(address to, uint256 amount) internal {
128 | if (to == address(0)) revert VAIZeroAddress();
129 | totalSupply += amount;
130 | unchecked {
131 | balanceOf[to] += amount;
132 | }
133 | emit Transfer(address(0), to, amount);
134 | }
135 |
136 | function _burn(address from, uint256 amount) internal {
137 | uint256 fromBal = balanceOf[from];
138 | if (fromBal < amount) revert VAIInsufficientBalance();
139 | unchecked {
140 | balanceOf[from] = fromBal - amount;
141 | totalSupply -= amount;
142 | }
143 | emit Transfer(from, address(0), amount);
144 | }
145 | }
146 |
Vow.sol
EVM Core Contract
Commentary: No commentary focus available.
1 | // SPDX-License-Identifier: MIT
2 | pragma solidity ^0.8.23;
3 |
4 | /// @notice Minimal surplus/deficit accounting inspired by Maker `Vow`.
5 | contract Vow {
6 | event Rely(address indexed usr);
7 | event Deny(address indexed usr);
8 | event File(bytes32 indexed what, uint256 data);
9 | event File(bytes32 indexed what, address data);
10 | event Fess(uint256 tab);
11 | event Heal(uint256 rad);
12 | event Kiss(uint256 rad);
13 | event Feed(uint256 rad);
14 |
15 | error VowAuth();
16 | error VowBounds();
17 |
18 | mapping(address => uint256) public wards;
19 |
20 | address public flap;
21 | address public flop;
22 | uint256 public Sin;
23 | uint256 public Joy;
24 | uint256 public hump;
25 | uint256 public live = 1;
26 |
27 | bytes32 private constant WHAT_HUMP = keccak256("hump");
28 | bytes32 private constant WHAT_LIVE = keccak256("live");
29 | bytes32 private constant WHAT_FLAP = keccak256("flap");
30 | bytes32 private constant WHAT_FLOP = keccak256("flop");
31 |
32 | modifier auth() {
33 | if (wards[msg.sender] != 1) revert VowAuth();
34 | _;
35 | }
36 |
37 | constructor(address owner_) {
38 | wards[owner_] = 1;
39 | emit Rely(owner_);
40 | }
41 |
42 | function rely(address usr) external auth {
43 | wards[usr] = 1;
44 | emit Rely(usr);
45 | }
46 |
47 | function deny(address usr) external auth {
48 | wards[usr] = 0;
49 | emit Deny(usr);
50 | }
51 |
52 | function file(bytes32 what, uint256 data) external auth {
53 | if (what == WHAT_HUMP) {
54 | hump = data;
55 | } else if (what == WHAT_LIVE) {
56 | live = data;
57 | } else {
58 | revert VowBounds();
59 | }
60 | emit File(what, data);
61 | }
62 |
63 | function file(bytes32 what, address data) external auth {
64 | if (what == WHAT_FLAP) {
65 | flap = data;
66 | } else if (what == WHAT_FLOP) {
67 | flop = data;
68 | } else {
69 | revert VowBounds();
70 | }
71 | emit File(what, data);
72 | }
73 |
74 | function fess(uint256 tab) external auth {
75 | Sin += tab;
76 | emit Fess(tab);
77 | }
78 |
79 | function heal(uint256 rad) external auth {
80 | if (rad > Sin || rad > Joy) revert VowBounds();
81 | unchecked {
82 | Sin -= rad;
83 | Joy -= rad;
84 | }
85 | emit Heal(rad);
86 | }
87 |
88 | function kiss(uint256 rad) external auth {
89 | if (rad > Sin) revert VowBounds();
90 | Sin -= rad;
91 | emit Kiss(rad);
92 | }
93 |
94 | function feed(uint256 rad) external auth {
95 | Joy += rad;
96 | emit Feed(rad);
97 | }
98 | }
99 |
100 |
Diagnostics Package
1 files captured
| # | Artifact | Bytes | Type |
|---|---|---|---|
| 1 | index.html | 13667 | html |
Recent Audit Runs
| Run | Status | Findings | Created |
|---|---|---|---|
| evmbench-20260220-141106 | PASS | 0 | 2/20/2026 2:11:07 PM |
| evmbench-20260220-140348 | PASS | 0 | 2/20/2026 2:03:49 PM |
| evmbench-20260220-140146 | PASS | 0 | 2/20/2026 2:01:46 PM |
| evmbench-20260220-133630 | PASS | 0 | 2/20/2026 1:36:31 PM |
| evmbench-20260220-133433 | FAILED | 0 | 2/20/2026 1:34:34 PM |
| evmbench-20260220-133143 | FAILED | 0 | 2/20/2026 1:31:44 PM |
| evmbench-20260220-133031 | FAILED | 0 | 2/20/2026 1:30:32 PM |
| evmbench-20260220-132918 | FAILED | 0 | 2/20/2026 1:29:19 PM |