@@ -10,16 +10,22 @@ import {Flyover} from "./libraries/Flyover.sol";
1010import {Quotes} from "./libraries/Quotes.sol " ;
1111import {SignatureValidator} from "./libraries/SignatureValidator.sol " ;
1212
13-
13+ /// @title PegIn
14+ /// @notice This contract is used to handle the peg in of the Bitcoin network to the Rootstock network
15+ /// @author Rootstock Labs
1416contract PegInContract is
1517 OwnableDaoContributorUpgradeable ,
1618 IPegIn {
1719
20+ /// @notice This struct is used to store the information of a call on behalf of the user
21+ /// @param timestamp The timestamp of the call
22+ /// @param success Whether the call was successful or not
1823 struct Registry {
1924 uint256 timestamp;
2025 bool success;
2126 }
2227
28+ /// @notice The version of the contract
2329 string constant public VERSION = "1.0.0 " ;
2430 Flyover.ProviderType constant private _PEG_TYPE = Flyover.ProviderType.PegIn;
2531 uint256 constant private _REFUND_ADDRESS_LENGTH = 21 ;
@@ -40,8 +46,13 @@ contract PegInContract is
4046
4147 uint256 private _minPegIn;
4248 bool private _mainnet;
49+ /// @notice The dust threshold for the peg in. If the difference between the amount paid and the amount required
50+ /// is more than this value, the difference goes back to the user's wallet
4351 uint256 public dustThreshold;
4452
53+ /// @notice Emitted when the dust threshold is set
54+ /// @param oldThreshold The old dust threshold
55+ /// @param newThreshold The new dust threshold
4556 event DustThresholdSet (uint256 indexed oldThreshold , uint256 indexed newThreshold );
4657
4758 // solhint-disable-next-line comprehensive-interface
@@ -55,8 +66,10 @@ contract PegInContract is
5566 /// @param owner the owner of the contract
5667 /// @param bridge the address of the Rootstock bridge
5768 /// @param dustThreshold_ the dust threshold for the peg in
69+ /// @param minPegIn the minimum peg in amount supported by the bridge
5870 /// @param collateralManagement the address of the Collateral Management contract
59- /// @param daoFeePercentage the percentage of the peg out amount that goes to the DAO.
71+ /// @param mainnet whether the contract is on the mainnet or not
72+ /// @param daoFeePercentage the percentage of the peg in amount that goes to the DAO.
6073 /// Use zero to disable the DAO integration feature
6174 /// @param daoFeeCollector the address of the DAO fee collector
6275 // solhint-disable-next-line comprehensive-interface
@@ -98,13 +111,15 @@ contract PegInContract is
98111 dustThreshold = threshold;
99112 }
100113
114+ /// @inheritdoc IPegIn
101115 function deposit () external payable override {
102116 if (! _collateralManagement.isRegistered (_PEG_TYPE, msg .sender )) {
103117 revert Flyover.ProviderNotRegistered (msg .sender );
104118 }
105119 _increaseBalance (msg .sender , msg .value );
106120 }
107121
122+ /// @inheritdoc IPegIn
108123 function withdraw (uint256 amount ) external nonReentrant override {
109124 uint256 balance = _balances[msg .sender ];
110125 if (balance < amount) {
@@ -118,6 +133,7 @@ contract PegInContract is
118133 }
119134 }
120135
136+ /// @inheritdoc IPegIn
121137 function callForUser (
122138 Quotes.PegInQuote calldata quote
123139 ) external payable nonReentrant override returns (bool ) {
@@ -168,6 +184,7 @@ contract PegInContract is
168184 return success;
169185 }
170186
187+ /// @inheritdoc IPegIn
171188 function registerPegIn (
172189 Quotes.PegInQuote calldata quote ,
173190 bytes calldata signature ,
@@ -213,16 +230,17 @@ contract PegInContract is
213230 return registerResult;
214231 }
215232
233+ /// @inheritdoc IPegIn
216234 function validatePegInDepositAddress (
217235 Quotes.PegInQuote calldata quote ,
218236 bytes calldata depositAddress
219237 ) external view override returns (bool ) {
220238 bytes32 derivationValue = keccak256 (
221- bytes .concat (
222- _hashPegInQuote (quote),
223- quote.btcRefundAddress,
224- bytes20 (quote.lbcAddress),
225- quote.liquidityProviderBtcAddress
239+ bytes .concat (
240+ _hashPegInQuote (quote),
241+ quote.btcRefundAddress,
242+ bytes20 (quote.lbcAddress),
243+ quote.liquidityProviderBtcAddress
226244 )
227245 );
228246 bytes memory flyoverRedeemScript = bytes .concat (
@@ -234,32 +252,56 @@ contract PegInContract is
234252 return BtcUtils.validateP2SHAdress (depositAddress, flyoverRedeemScript, _mainnet);
235253 }
236254
255+ /// @inheritdoc IPegIn
237256 function getBalance (address addr ) external view override returns (uint256 ) {
238257 return _balances[addr];
239258 }
240259
260+ /// @inheritdoc IPegIn
241261 function hashPegInQuote (Quotes.PegInQuote calldata quote ) external view override returns (bytes32 ) {
242262 return _hashPegInQuote (quote);
243263 }
244264
265+ /// @inheritdoc IPegIn
245266 function getQuoteStatus (bytes32 quoteHash ) external view override returns (PegInStates) {
246267 return _processedQuotes[quoteHash];
247268 }
248269
270+ /// @notice This function is used to increase the balance of an account
271+ /// @dev This function must remain private. Any exposure can lead to a loss of funds.
272+ /// It is responsibility of the caller to ensure that the account is a liquidity provider
273+ /// @param dest The address of account
274+ /// @param amount The amount of balance to increase
249275 function _increaseBalance (address dest , uint256 amount ) private {
250276 if (amount > 0 ) {
251277 _balances[dest] += amount;
252278 emit BalanceIncrease (dest, amount);
253279 }
254280 }
255281
282+ /// @notice This function is used to decrease the balance of an account
283+ /// @dev This function must remain private. Any exposure can lead to a loss of funds.
284+ /// It is responsibility of the caller to ensure that the account is a liquidity provider
285+ /// @param dest The address of account
286+ /// @param amount The amount of balance to decrease
256287 function _decreaseBalance (address dest , uint256 amount ) private {
257288 if (amount > 0 ) {
258289 _balances[dest] -= amount;
259290 emit BalanceDecrease (dest, amount);
260291 }
261292 }
262293
294+ /// @notice This function is used to register the peg in into the bridge
295+ /// @param quote The quote of the peg in
296+ /// @param btcRawTransaction The raw transaction of the peg in in the Bitcoin network,
297+ /// without the witness data
298+ /// @param partialMerkleTree The partial merkle tree proving the inclusion of the peg
299+ /// in transaction
300+ /// @param height The height of the peg in transaction
301+ /// @param derivationHash The hash of the quote used to derive the deposit address
302+ /// @return registerResult The result of the registration. It can be:
303+ /// - A negative value: An error code returned by the bridge
304+ /// - A positive value: The amount of the peg in transaction
263305 function _registerBridge (
264306 Quotes.PegInQuote memory quote ,
265307 bytes memory btcRawTransaction ,
@@ -279,12 +321,22 @@ contract PegInContract is
279321 );
280322 }
281323
324+ /// @notice This function is used by the registerPegIn function to handle the scenarios
325+ /// where the liquidity provider has already called the callForUser function
326+ /// @dev This function makes an external call, therefore it might be exposed to a reentrancy attack,
327+ /// the caller must have the nonReentrant modifier or any kind of reentrancy protection. Not all the
328+ /// modifications to the state can be done before the call as some of them depend on the result of the
329+ /// call itself
330+ /// @param quote The quote of the peg in
331+ /// @param quoteHash The hash of the quote
332+ /// @param callSuccessful Whether the call on behalf of the user was successful or not
333+ /// @param transferredAmount The amount of the peg in transaction
282334 function _registerCallDone (
283335 Quotes.PegInQuote calldata quote ,
284336 bytes32 quoteHash ,
285337 bool callSuccessful ,
286338 uint256 transferredAmount
287- ) private { // this doesn't have the nonReentrant modifier because the caller registerPegIn has it
339+ ) private {
288340 uint refundAmount;
289341 if (callSuccessful) {
290342 refundAmount = _min (transferredAmount, quote.value + quote.callFee + quote.gasFee);
@@ -316,6 +368,15 @@ contract PegInContract is
316368 }
317369 }
318370
371+ /// @notice This function is used by the registerPegIn function to handle the scenarios
372+ /// where the liquidity provider has not called the callForUser function
373+ /// @dev This function makes an external call, therefore it might be exposed to a reentrancy attack,
374+ /// the caller must have the nonReentrant modifier or any kind of reentrancy protection. Not all the
375+ /// modifications to the state can be done before the call as some of them depend on the result of the
376+ /// call itself
377+ /// @param quote The quote of the peg in
378+ /// @param quoteHash The hash of the quote
379+ /// @param transferredAmount The amount of the peg in transaction
319380 function _registerCallNotDone (
320381 Quotes.PegInQuote calldata quote ,
321382 bytes32 quoteHash ,
@@ -358,6 +419,15 @@ contract PegInContract is
358419 }
359420 }
360421
422+ /// @notice This function is used to validate the parameters of the registerPegIn function
423+ /// @dev The validations include:
424+ /// - If the quote was already registered
425+ /// - If the signature provided by the liquidity provider is valid
426+ /// - If the height is supported by the Rootstock bridge
427+ /// @param quote The quote of the peg in
428+ /// @param quoteHash The hash of the quote
429+ /// @param height The height of the peg in transaction
430+ /// @param signature The signature of the quoteHash by the liquidity provider
361431 function _validateRegisterParams (
362432 Quotes.PegInQuote calldata quote ,
363433 bytes32 quoteHash ,
@@ -376,6 +446,16 @@ contract PegInContract is
376446 }
377447 }
378448
449+ /// @notice This function is used to hash a peg in quote
450+ /// @dev The function also validates the following:
451+ /// - The quote belongs to this contract
452+ /// - The quote destination is not the bridge contract
453+ /// - The quote BTC refund address is valid
454+ /// - The quote liquidity provider BTC address is valid
455+ /// - The quote total amount is greater than the bridge minimum peg in amount
456+ /// - The sum of the timestamp values is not greater than the maximum uint32 value
457+ /// @param quote The peg in quote
458+ /// @return quoteHash The hash of the quote
379459 function _hashPegInQuote (Quotes.PegInQuote calldata quote ) private view returns (bytes32 ) {
380460 if (address (this ) != quote.lbcAddress) {
381461 revert Flyover.IncorrectContract (address (this ), quote.lbcAddress);
@@ -399,6 +479,12 @@ contract PegInContract is
399479 return keccak256 (Quotes.encodeQuote (quote));
400480 }
401481
482+ /// @notice This function is used to determine if the liquidity provider should be penalized
483+ /// @param quote The peg in quote
484+ /// @param amount The amount of the peg in transaction
485+ /// @param callTimestamp The timestamp of the call on behalf of the user
486+ /// @param height The height of the peg in transaction
487+ /// @return shouldPenalize Whether the liquidity provider should be penalized or not
402488 function _shouldPenalize (
403489 Quotes.PegInQuote calldata quote ,
404490 int256 amount ,
@@ -445,6 +531,7 @@ contract PegInContract is
445531 return false ;
446532 }
447533
534+ /// @dev Utility function to return the minimum of two uint256 values
448535 function _min (uint a , uint b ) private pure returns (uint ) {
449536 return a < b ? a : b;
450537 }
0 commit comments