- CCIP/trustless bridge contracts, GRU tokens, DEX/PMM tests, reserve vault. - Token-aggregation service routes, planner, chain config, relay env templates. - Config snapshots and multi-chain deployment markdown updates. - gitignore services/btc-intake/dist/ (tsc output); do not track dist. Run forge build && forge test before deploy (large solc graph). Made-with: Cursor
83 lines
2.6 KiB
Solidity
83 lines
2.6 KiB
Solidity
// SPDX-License-Identifier: MIT
|
|
pragma solidity ^0.8.20;
|
|
|
|
import "@openzeppelin/contracts/access/AccessControl.sol";
|
|
|
|
contract AtomicFeePolicy is AccessControl {
|
|
bytes32 public constant POLICY_MANAGER_ROLE = keccak256("POLICY_MANAGER_ROLE");
|
|
|
|
struct CorridorPolicy {
|
|
uint16 fulfillerFeeBps;
|
|
uint16 protocolFeeBps;
|
|
uint16 bondBps;
|
|
uint16 slashPenaltyBps;
|
|
uint256 maxFulfilmentDelay;
|
|
uint256 maxSettlementDelay;
|
|
}
|
|
|
|
mapping(bytes32 => CorridorPolicy) public corridorPolicies;
|
|
|
|
event CorridorPolicySet(
|
|
bytes32 indexed corridorId,
|
|
uint16 fulfillerFeeBps,
|
|
uint16 protocolFeeBps,
|
|
uint16 bondBps,
|
|
uint16 slashPenaltyBps,
|
|
uint256 maxFulfilmentDelay,
|
|
uint256 maxSettlementDelay
|
|
);
|
|
|
|
constructor(address admin) {
|
|
_grantRole(DEFAULT_ADMIN_ROLE, admin);
|
|
_grantRole(POLICY_MANAGER_ROLE, admin);
|
|
}
|
|
|
|
function setCorridorPolicy(
|
|
bytes32 corridorId,
|
|
uint16 fulfillerFeeBps,
|
|
uint16 protocolFeeBps,
|
|
uint16 bondBps,
|
|
uint16 slashPenaltyBps,
|
|
uint256 maxFulfilmentDelay,
|
|
uint256 maxSettlementDelay
|
|
) external onlyRole(POLICY_MANAGER_ROLE) {
|
|
corridorPolicies[corridorId] = CorridorPolicy({
|
|
fulfillerFeeBps: fulfillerFeeBps,
|
|
protocolFeeBps: protocolFeeBps,
|
|
bondBps: bondBps,
|
|
slashPenaltyBps: slashPenaltyBps,
|
|
maxFulfilmentDelay: maxFulfilmentDelay,
|
|
maxSettlementDelay: maxSettlementDelay
|
|
});
|
|
emit CorridorPolicySet(
|
|
corridorId,
|
|
fulfillerFeeBps,
|
|
protocolFeeBps,
|
|
bondBps,
|
|
slashPenaltyBps,
|
|
maxFulfilmentDelay,
|
|
maxSettlementDelay
|
|
);
|
|
}
|
|
|
|
function quoteFees(bytes32 corridorId, uint256 amountIn)
|
|
external
|
|
view
|
|
returns (uint256 fulfillerFee, uint256 protocolFee)
|
|
{
|
|
CorridorPolicy memory policy = corridorPolicies[corridorId];
|
|
fulfillerFee = (amountIn * policy.fulfillerFeeBps) / 10_000;
|
|
protocolFee = (amountIn * policy.protocolFeeBps) / 10_000;
|
|
}
|
|
|
|
function requiredBond(bytes32 corridorId, uint256 reservedLiquidity) external view returns (uint256) {
|
|
CorridorPolicy memory policy = corridorPolicies[corridorId];
|
|
uint256 effectiveBps = policy.bondBps;
|
|
uint256 slashFloor = 10_000 + policy.slashPenaltyBps;
|
|
if (effectiveBps < slashFloor) {
|
|
effectiveBps = slashFloor;
|
|
}
|
|
return (reservedLiquidity * effectiveBps) / 10_000;
|
|
}
|
|
}
|