|
| 1 | +// SPDX-License-Identifier: GPL-3.0-only |
| 2 | + |
| 3 | +pragma solidity 0.8.17; |
| 4 | + |
| 5 | +/// @notice Interface for TBTCVault migration debt accounting. |
| 6 | +interface ITBTCVaultMigrationDebt { |
| 7 | + event MigrationDebtRegistered(address indexed revealer, uint256 amount); |
| 8 | + event MigrationDebtRepaid(address indexed revealer, uint256 remaining); |
| 9 | + event MigrationDebtCleared(address indexed revealer, uint256 amount); |
| 10 | + event MigrationRevealerSet(address indexed revealer, bool allowed); |
| 11 | + |
| 12 | + /// @notice Registers the expected total migration debt for a revealer. |
| 13 | + /// Must be called before revealing migration-tagged deposits. |
| 14 | + /// The revealer cannot reveal migration deposits without an |
| 15 | + /// outstanding debt registration (enforced by |
| 16 | + /// `canRevealMigration`). |
| 17 | + /// @dev The `amount` parameter should represent the expected total BTC |
| 18 | + /// value of migration deposits for this revealer, converted to |
| 19 | + /// 1e18 Ethereum precision. |
| 20 | + /// |
| 21 | + /// Amount convention trade-off: the caller must decide whether to |
| 22 | + /// register the gross (pre-fee) deposit value or an estimated net |
| 23 | + /// (post-fee) value: |
| 24 | + /// |
| 25 | + /// Gross registration (registering the full pre-fee deposit |
| 26 | + /// amount): conservative approach. After the Bridge sweeps the |
| 27 | + /// deposit, it deducts a treasury fee per deposit |
| 28 | + /// (`depositAmount / depositTreasuryFeeDivisor`) and a share of |
| 29 | + /// the Bitcoin sweep transaction miner fee |
| 30 | + /// (`depositTxFeeIncurred`). The post-fee amount reaching the |
| 31 | + /// vault is less than the registered debt, leaving a residual |
| 32 | + /// positive debt. Migration lifecycle completion requires an |
| 33 | + /// owner-initiated `notifyMigrationSweep` call to transition |
| 34 | + /// the reserve to MIGRATED state. This approach avoids excess |
| 35 | + /// tBTC minting. |
| 36 | + /// |
| 37 | + /// Net registration (estimating post-fee value): if the fee |
| 38 | + /// estimate matches actual deductions, debt reaches zero |
| 39 | + /// automatically on sweep and triggers the migration completion |
| 40 | + /// callback. However, the Bitcoin miner fee component is |
| 41 | + /// unknowable at registration time since it depends on the |
| 42 | + /// sweep batch composition and Bitcoin fee market conditions. |
| 43 | + /// Underestimating fees causes excess tBTC minting; |
| 44 | + /// overestimating fees leaves residual debt requiring owner |
| 45 | + /// intervention. |
| 46 | + /// |
| 47 | + /// Registration is one-time: reverts if the revealer already has |
| 48 | + /// outstanding debt. |
| 49 | + /// @param revealer The address that will reveal migration-tagged |
| 50 | + /// deposits on the Bridge. |
| 51 | + /// @param amount Expected migration debt in 1e18 Ethereum precision |
| 52 | + /// (satoshi values are scaled by SATOSHI_MULTIPLIER = 10^10). |
| 53 | + function registerMigrationDebt(address revealer, uint256 amount) external; |
| 54 | + |
| 55 | + function migrationDebt(address revealer) external view returns (uint256); |
| 56 | + |
| 57 | + /// @notice Clears any remaining migration debt for `revealer`. |
| 58 | + /// @dev Intended for the over-registration residual-debt case once the |
| 59 | + /// migration lifecycle has been completed out-of-band and no further |
| 60 | + /// migration deposits should be revealed for this address. |
| 61 | + /// Implementations should zero the debt, update aggregate debt |
| 62 | + /// accounting, and disable migration reveals for `revealer`. |
| 63 | + /// @param revealer The revealer whose residual migration debt should be |
| 64 | + /// cleared. |
| 65 | + function clearMigrationDebt(address revealer) external; |
| 66 | + |
| 67 | + function setMigrationRevealer(address revealer, bool allowed) external; |
| 68 | + |
| 69 | + function isMigrationRevealer(address revealer) |
| 70 | + external |
| 71 | + view |
| 72 | + returns (bool); |
| 73 | + |
| 74 | + /// @notice Returns whether the given revealer is allowed to reveal |
| 75 | + /// migration-tagged deposits. |
| 76 | + /// @dev Returns true only when both `isMigrationRevealer[revealer]` |
| 77 | + /// is set and `migrationDebt[revealer] > 0`. This ensures a |
| 78 | + /// revealer cannot reveal migration deposits without a |
| 79 | + /// corresponding debt registration, and cannot reveal beyond |
| 80 | + /// the registered capacity once debt is fully repaid. |
| 81 | + /// @param revealer Address to check migration reveal eligibility. |
| 82 | + /// @return True if the revealer can reveal migration deposits. |
| 83 | + function canRevealMigration(address revealer) external view returns (bool); |
| 84 | + |
| 85 | + /// @notice Returns whether this vault has any outstanding migration debt |
| 86 | + /// across all revealers. |
| 87 | + /// @dev Implementations should maintain an internal counter that is |
| 88 | + /// incremented when migration debt is registered and decremented |
| 89 | + /// when a revealer's debt reaches zero, whether via repayment or an |
| 90 | + /// owner-authorized residual debt clear-out. This provides an O(1) |
| 91 | + /// aggregate query without enumerating individual revealers. |
| 92 | + /// @return True if at least one revealer has nonzero migration debt. |
| 93 | + function hasOutstandingMigrationDebt() external view returns (bool); |
| 94 | +} |
0 commit comments