# Relay Guild: Fee Collector MVP Contract
## Statement of Work
This proposal outlines the work required to implement an MVP contract for the [Aestus](https://aestus.live/) [MEV-Boost relay](https://www.relayscan.io/) team to charge service fees to participating block builders. [A preliminary scope of the problem space can be found here.](https://hackmd.io/@austonst-aestus/r1dQPeCl6)
## Scope
The project focuses on writing an initial fee collector contract MVP that allows Aestus MEV-Boost relay guild to charge registered block builders a small fee from their deposited collateral.
### Project Requirements
The following is a list of general requirements. Actual contract properties, function implementation and contract events may differ on the go.
- A fee collector contract should have the following properties:
- A mapping of builders ETH address to builder props:
- pubKeys: bytes[][48] // builder can register n pubKeys
- active: bool // status
- totalBalance: uint256 // total builder deposited collateral
- withdrawAtNextReconciliation: bool // builder signals to withdraw remaining collateral at next reconciliation
- withdrawableBalance: uint256 // builder available collateral to withdraw
- Service fee parameters:
- currentFee: uint256 // current service fee (<= 1e6 (100%)) until next reconciliation
- nextEpochFee: uint256 // useful for advanced notice to builders
- nextReconciliationBlock: // block from where the next reconciliation can be executed
- lastReconciationBlock // keeps track of block when last reconciliation took place
- Guild Safe multisig address
- Owner address
- A new fee collector contract should require a Safe multisig and a owner role addresses as parameters.
- Would be good to also provide initial service fee parameters.
- Service fee parameters should have default values during deployment.
- MEV-Boost Relay Fee collector contract aims to charge a small fee (0.5% block value) on a regular schedule to participating builders.
- Service fee should be updated by the owner role at any time
- MEV-Boost Guild accepts new builders onto their relay by requesting their BLS public key (BLS12-381 48 bytes length), ETH address and **an optional** minimum ETH-denominated upfront deposit or collateral to become eligible for submitting blocks to proposing validators.
- Validate pubkeys aren't registered to more than one builder
- New builders can be registered by themselves or by the owner
- Builders should be able to call a `deposit` function at any time to add collateral for their operations.
- Builders should be able to update (add/remove) their pubKeys list
- Registered builders should be able to withdraw any remaining collateral **only after** the next **reconciliation** is executed.
- They sould be able to call a `withdrawAtNextReconciliation()` function so set `withdrawAtNextReconciliation=true`
- On a regular schedule (e.g. weekly, 1000 slot window) the Guild uses an off-chain accounting system to calculate accumulated fees on a block-by-block basis. This data is then fed to the contact to **reconcile** builder collateral balances and forward charged fees to the Guild multisig (Safe), while remaining balances from builders marked as `withdrawAtNextReconciliation=rue` should be accounted as withdrawable.
- Builders with no collateral should be marked as `active = false`.
- Builders then should be able to call a withdraw function (it's better to implement a. Pull over push pattern)
- ~~allow builders to send a flag if they want to fully exit the guild, if so, their record is deleted from the registry.~~
- ~~Instead of sending a `reconcileSlot` parameter, I recommend sending a nextReconciliationBlock to update service fee paramters as follows:~~
- ~~`currentFee = nextEpochFee`~~
- ~~`nextReconciliationBlock = _nextReconciliationBlock`~~
- The `reconcile` function should be callable **only** after `tx.block > nextReconciliationBlock`
- **this kind modifier should be considered in V2**
- Contract owner should be able to call `setServiceFee` to update `currentFee`, `nextEpochFee` and `nextReconciliationBlock`
- ~~I recommend just sending `nextEpochFee` and `nextReconciliationBlock` so this can be called only if you really looking to update the fee, otherwise `currentFee` and `nextReconciliationBlock` would be updated in the last reconciliation call.~~
- Contract should emit the neccesary events to allow the guild to fetch the data structures defined in their spec document (list of builders, deposts, reconciliation events).
- Contract should allow room to plug in governance in the future (accountability of any action to be performed by Ownable role).
- Contract should be upgradable.
### Nice to have (probably not included in the first MVP)
- Verify BLS public key ownership at the contact level (currently Solidity doesn't support BLS signature natively)
- Still need to dig into this https://ethresear.ch/t/bls-signatures-in-solidity/7919
# Deliverables
1. **Contract repository**: a (**private) repository using Foundry
3. **Comprehensive Documentation**: contracts will be fully covered with natspec documentation
4. **Tested Solution**: A complete suite of unit tests covering the MVP features.
# Process
1. **Initial Review**: Begin with a comprehensive review of the current spec to understand MVP requirements.
2. **Development**: Implement the changes as outlined in the scope.
3. **Testing**: After development, test the system using the provided examples and any additional test cases deemed necessary.
4. **Documentation**: write detailed documentation and how to use the project repository.
5. **Feedback & Revisions**: Seek feedback on the implementation and make any necessary revisions.
# Proposal
| Phases | Description | ETA |
| -------- | -------- | -------- |
| **Review** | Comprehensive review of the current spec & proposal. | 0.5 day |
| **Development** | Implement contract logic. | 1.5 day |
| **Testing** | Thoroughly test the contract using provided examples. | 1.5 day |
| **Documentation** | Write necessary documentation. | 0.5 day |
| **Feedback & Revisions** | Address feedback and make necessary revisions. | 1 day |
| **Total** | | **2.5 ETH** |
**Total Estimated Time**: 5 days
## Estimated Time
- 40 Hours
## Payout
- 2.5 ETH (Ethereum/Optimism)