# Chainlink CRE (https://docs.helico.site/docs/chainlink-cre)

The confidential workflow that makes the only decision the product has.

The decision runs inside a Chainlink CRE enclave, registered with `cre.handlerInTee`. The logic
is a package, [`@helico/plugin-cre`](https://github.com/0xHelico/helico/tree/main/packages/plugins/cre), so 116 unit tests
cover it without the CLI; [`apps/cre`](https://github.com/0xHelico/helico/tree/main/apps/cre) is what the CLI compiles.

## Every run
1. `getSecrets` releases six of the seven mandate fields from the Vault DON into the enclave;
   the enclave recomputes `keccak256(abi.encode(Mandate))` and stops if it differs from the
   configured hash.
2. Two `eth_call` batches from inside the enclave: the account from the vault, the pool's
   price, fee and liquidity from `StateView`, the position from the `PositionManager`.
3. Decide: hold on expiry, cooldown, or in range; otherwise a range of exactly
   `rangeWidthTicks` centred on the tick, only if a mirror of the vault's `_checkRange` accepts
   it.
4. Size: what the burn returns, the swap that funds the other side, bounded inside the new
   range, and the liquidity that funds. Below `minRetainedBps` is a hold.
5. Cross out with the verdict only. `delivery: 'forwarder'` writes
   `abi.encode(bool act, bytes32 mandateHash, RecenterParams p)` to the vault's `onReport`;
   `delivery: 'signature'` signs an EIP-712 authorisation with a key that never leaves.

The binary is public. What stays inside is the data, the RPC traffic, and the intermediate
values. The mandate hash proves consistency, not secrecy.

## Config
`schedule`, `rpcUrl`, `delivery`, `vault`, `positionManager`, `stateView`, `owner`, `poolId`,
`mandateHash`, `gasLimit`, `slippageBps`, `maxPoolFeePips`, `deadlineSeconds`; for
`signature` also `chainId`; for `forwarder` also `chainSelectorName`
(`ethereum-mainnet-arbitrum-1`). `secrets.yaml` maps the six mandate fields, and in signature
mode `AGENT_KEY`, to env vars.

## On Arbitrum One
|                                                                             |                                                                                                                                            |
| --------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `KeystoneForwarder`, production                                             | `0xF8344CFd5c43616a4366C34E3EEE75af79a74482`                                                                                               |
| `MockKeystoneForwarder`, what `simulate --broadcast` uses; verifies nothing | `0xd770499057619c9a76205fd4168161cf94abc532`                                                                                               |
| v4 `PoolManager` / `StateView` / `PositionManager`                          | `0x360E68faCcca8cA495c1B759Fd9EEe466db9FB32` / `0x76Fd297e2D437cd7f76d50F01AfE6160f86e9990` / `0xd88F38F930b7952f2DB2432Cb002E7abbF3dD869` |
| Demo pool, ETH/ARB 0.05%                                                    | `0xb37da7d5beb04539b6c497a15794748fc0ce1da7afc61133e3253eff76229ae5`                                                                       |

## What the simulation proves
> **warn:** In the simulator the enclave is the simulator and the forwarder is the mock. A run proves the
delivery path and the vault's execution, not DON authorisation. Chainlink's qualification text
accepts a CRE CLI simulation as evidence; a live deployment additionally needs the Confidential
Workflows beta.

> **error:** `KeystoneForwarder` calls the receiver inside a `try`. A reverting `onReport` still leaves a
transaction with `status 1`. `rehearse.sh` reads `positionOf` before and after and only counts
a position that changed. That is how [#78](https://github.com/0xHelico/helico/issues/78) was found.

## Where to look
|                                    |                                                                                                                                                         |
| ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `handlerInTee` registration        | [`index.ts#L268-L276`](https://github.com/0xHelico/helico/blob/049f7d848d680a17cca5f4c1ba664ebffd7ea69d/packages/plugins/cre/src/index.ts#L268-L276)    |
| the confidential handler           | [`index.ts#L173-L234`](https://github.com/0xHelico/helico/blob/049f7d848d680a17cca5f4c1ba664ebffd7ea69d/packages/plugins/cre/src/index.ts#L173-L234)    |
| the decision                       | [`index.ts#L111-L170`](https://github.com/0xHelico/helico/blob/049f7d848d680a17cca5f4c1ba664ebffd7ea69d/packages/plugins/cre/src/index.ts#L111-L170)    |
| reads from inside the enclave      | [`chain.ts#L20-L44`](https://github.com/0xHelico/helico/blob/049f7d848d680a17cca5f4c1ba664ebffd7ea69d/packages/plugins/cre/src/chain.ts#L20-L44)        |
| the verdict delivered to the vault | [`index.ts#L244-L265`](https://github.com/0xHelico/helico/blob/049f7d848d680a17cca5f4c1ba664ebffd7ea69d/packages/plugins/cre/src/index.ts#L244-L265)    |
| the vault receiving it             | [`HelicoVault.sol#L469-L482`](https://github.com/0xHelico/helico/blob/049f7d848d680a17cca5f4c1ba664ebffd7ea69d/contracts/src/HelicoVault.sol#L469-L482) |

Check it: `bun run --filter @helico/plugin-cre typecheck` and `... test`.
