SafeHarborAdopter
Inherits: ISafeHarborAdopter
Title: SafeHarborAdopter
Authors: David Dada <daveproxy80@gmail.com> (https://github.com/dadadave80), Integrates the SEAL Whitehat Safe Harbor (https://github.com/security-alliance/safe-harbor)
Stateless Diamond facet letting a diamond adopt the SEAL Whitehat Safe Harbor agreement on-chain — the legal half of incident response, complementing EmergencyStop.
All logic lives in SafeHarborAdopterLib. The diamond calls the SEAL registry itself
(msg.sender == diamond). All state-changing functions are gated on SAFE_HARBOR_ADMIN_ROLE,
managed through the diamond's AccessControl module; the registry + factory are supplied at init
and rotated per chain. VERIFY the deployed SEAL addresses + AgreementDetails ABI for your chain
before mainnet use.
This facet covers only the on-chain half of adoption: creating and registering an agreement (createAndAdopt) or registering a pre-deployed one (adoptSafeHarbor). SEAL's adoption procedure has three final steps (https://github.com/security-alliance/safe-harbor/blob/78ba9237377a9622439cbab41a5336673cea1b92/README.md#protocol-adoption). The adopting protocol does the first two off-chain; this facet makes the third:
- Publish an Agreement Fact Page with every detail of the adoption, maintained off-chain for anyone to view.
- Add the agreement's Exhibit D (User Adoption Procedures), adapted, to its terms of service.
- Make the registry call from its decision-making authority. That call is the legally binding
step. The diamond makes it through this facet and is recorded as the adopter, so the call must
come from the protocol's governance: grant
SAFE_HARBOR_ADMIN_ROLEonly to it (for example its Governor-controlled TimelockController), never to an operator key, and keepDEFAULT_ADMIN_ROLE, which administers that role, with the same authority. The agreement's owner (theownerargument of createAndAdopt, or the owner of a pre-deployed agreement passed to adoptSafeHarbor) must be that same authority too: after adoption the owner alone can change the agreement's chains, accounts, asset-recovery addresses and bounty terms. Lattice itself has not adopted Safe Harbor; see the Safe Harbor section of SECURITY.md.
Notes:
- lattice-version: 0.1.0
- lattice-source: Lattice original
Functions
adoptSafeHarbor
Adopts a pre-deployed agreement for this diamond via the configured registry.
Gated on SAFE_HARBOR_ADMIN_ROLE. The diamond calls the registry itself, so it is recorded
as the adopter. Re-adopting overwrites the prior agreement (the update path).
function adoptSafeHarbor(address agreement) external virtual;Parameters
| Name | Type | Description |
|---|---|---|
| agreement | address | The agreement contract to adopt. |
createAndAdopt
Creates an agreement (recovery addresses + bounty terms) via the configured factory and adopts it for this diamond, in one governed call.
Gated on SAFE_HARBOR_ADMIN_ROLE. This is where the security-critical recovery addresses
are set, so the whole action is role-pinned.
function createAndAdopt(AgreementDetails calldata details, address chainValidator, address owner, bytes32 salt)
external
virtual
returns (address);Parameters
| Name | Type | Description |
|---|---|---|
| details | AgreementDetails | The agreement details (per-chain recovery address, accounts, bounty terms). |
| chainValidator | address | The SEAL ChainValidator contract for this chain. |
| owner | address | The owner of the new agreement (may later update its terms). |
| salt | bytes32 | A caller-provided salt for CREATE2 uniqueness. |
Returns
| Name | Type | Description |
|---|---|---|
| <none> | address | The newly created and adopted agreement address. |
setSafeHarborRegistry
Sets or rotates the Safe Harbor registry (per-chain configuration).
Gated on SAFE_HARBOR_ADMIN_ROLE. Reverts SafeHarborAdopterZeroRegistry for a zero address.
function setSafeHarborRegistry(address registry) external virtual;Parameters
| Name | Type | Description |
|---|---|---|
| registry | address | The Safe Harbor registry to use. |
setAgreementFactory
Sets or rotates the agreement factory (per-chain configuration).
Gated on SAFE_HARBOR_ADMIN_ROLE. Reverts SafeHarborAdopterZeroFactory for a zero address.
function setAgreementFactory(address factory) external virtual;Parameters
| Name | Type | Description |
|---|---|---|
| factory | address | The agreement factory to use. |
safeHarborRegistry
Returns the configured Safe Harbor registry.
function safeHarborRegistry() external view virtual returns (address);Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
agreementFactory
Returns the configured agreement factory.
function agreementFactory() external view virtual returns (address);Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
safeHarborAgreement
Returns the agreement currently adopted by this diamond (zero if none).
function safeHarborAgreement() external view virtual returns (address);Returns
| Name | Type | Description |
|---|---|---|
| <none> | address |
exportSelectors
ERC-8153 selector export: this facet's cuttable selectors, tightly packed (4 bytes each).
Excludes exportSelectors() itself (0x0ef22643) - it is never cut into a diamond. Order matches
forge inspect SafeHarborAdopter methodIdentifiers (alphabetical by signature); kept in exact parity by
ExportSelectorsParityTest. Chunks:
adoptSafeHarbor(address) 0x344fbd20
agreementFactory() 0x4495ae68
createAndAdopt((string,(string,string)[],(string,(string,uint8)[],string)[],(uint256,uint256,bool,uint8,string,uint256),string),address,address,bytes32) 0x99ce8f17
safeHarborAgreement() 0x9bcc73cb
safeHarborRegistry() 0x23dbb9f6
setAgreementFactory(address) 0xb4e25f6f
setSafeHarborRegistry(address) 0xcfdf871f
function exportSelectors() external pure virtual returns (bytes memory selectors);Returns
| Name | Type | Description |
|---|---|---|
| selectors | bytes |