From 842722d87b48639df8e631e8c8d158ca4906bb08 Mon Sep 17 00:00:00 2001 From: sam bacha Date: Thu, 15 Aug 2024 22:33:25 -0700 Subject: [PATCH 1/8] feat(tokens): init support --- CHANGELOG.md | 14 ++ src/tokens/ERC20.sol | 78 +++++++ src/tokens/ERC20Collateral.sol | 64 ++++++ src/tokens/ERC721.sol | 76 +++++++ src/tokens/ERC721Collateral.sol | 75 +++++++ src/tokens/Native.sol | 83 +++++++ src/tokens/README.md | 7 + src/tokens/extensions/FastHypERC20.sol | 60 +++++ .../extensions/FastHypERC20Collateral.sol | 60 +++++ src/tokens/extensions/HypERC4626.sol | 102 +++++++++ .../extensions/HypERC4626Collateral.sol | 111 +++++++++ .../extensions/HypERC4626OwnerCollateral.sol | 91 ++++++++ .../extensions/HypERC721URICollateral.sol | 35 +++ src/tokens/extensions/HypERC721URIStorage.sol | 94 ++++++++ src/tokens/extensions/HypFiatToken.sol | 33 +++ src/tokens/extensions/HypNativeScaled.sol | 53 +++++ src/tokens/extensions/HypXERC20.sol | 29 +++ src/tokens/extensions/HypXERC20Lockbox.sol | 76 +++++++ src/tokens/interfaces/IFiatToken.sol | 24 ++ src/tokens/interfaces/IXERC20.sol | 78 +++++++ src/tokens/interfaces/IXERC20Lockbox.sol | 61 +++++ src/tokens/libs/FastTokenRouter.sol | 210 ++++++++++++++++++ src/tokens/libs/TokenMessage.sol | 31 +++ src/tokens/libs/TokenRouter.sol | 180 +++++++++++++++ 24 files changed, 1725 insertions(+) create mode 100644 CHANGELOG.md create mode 100755 src/tokens/ERC20.sol create mode 100755 src/tokens/ERC20Collateral.sol create mode 100755 src/tokens/ERC721.sol create mode 100755 src/tokens/ERC721Collateral.sol create mode 100755 src/tokens/Native.sol create mode 100755 src/tokens/README.md create mode 100755 src/tokens/extensions/FastHypERC20.sol create mode 100755 src/tokens/extensions/FastHypERC20Collateral.sol create mode 100755 src/tokens/extensions/HypERC4626.sol create mode 100755 src/tokens/extensions/HypERC4626Collateral.sol create mode 100755 src/tokens/extensions/HypERC4626OwnerCollateral.sol create mode 100755 src/tokens/extensions/HypERC721URICollateral.sol create mode 100755 src/tokens/extensions/HypERC721URIStorage.sol create mode 100755 src/tokens/extensions/HypFiatToken.sol create mode 100755 src/tokens/extensions/HypNativeScaled.sol create mode 100755 src/tokens/extensions/HypXERC20.sol create mode 100755 src/tokens/extensions/HypXERC20Lockbox.sol create mode 100755 src/tokens/interfaces/IFiatToken.sol create mode 100755 src/tokens/interfaces/IXERC20.sol create mode 100755 src/tokens/interfaces/IXERC20Lockbox.sol create mode 100755 src/tokens/libs/FastTokenRouter.sol create mode 100755 src/tokens/libs/TokenMessage.sol create mode 100755 src/tokens/libs/TokenRouter.sol diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..7adc3a2 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +### Changelog + +All notable changes to this project will be documented in this file. Dates are displayed in UTC. + +Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). + +#### v0.4.0 + +> 15 August 2024 + +- contracts setup [`#1`](https://github.com/sambacha/eigenlayer-template/pull/1) +- Removed .gitmodules [`fa96ba3`](https://github.com/sambacha/eigenlayer-template/commit/fa96ba3741ef9e7a6db1ff6d899b956c8dbaf0a7) +- Merge commit '03b4804bedd2e2db3e1e3c30cab1129155cb3066' as 'lib/openzeppelin-contracts-upgradeable' [`f05585f`](https://github.com/sambacha/eigenlayer-template/commit/f05585fb0a13b03d75a25aa43f606154ae7d2a31) +- Squashed 'lib/openzeppelin-contracts-upgradeable/' content from commit 723f8cab0 [`03b4804`](https://github.com/sambacha/eigenlayer-template/commit/03b4804bedd2e2db3e1e3c30cab1129155cb3066) diff --git a/src/tokens/ERC20.sol b/src/tokens/ERC20.sol new file mode 100755 index 0000000..be63c05 --- /dev/null +++ b/src/tokens/ERC20.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {TokenRouter} from "./libs/TokenRouter.sol"; + +import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; + +/** + * @title ERC20 Token Router that extends ERC20 with remote transfer functionality. + * @author Abacus Works + * @dev Supply on each chain is not constant but the aggregate supply across all chains is. + */ +contract HypERC20 is ERC20Upgradeable, TokenRouter { + uint8 private immutable _decimals; + + constructor(uint8 __decimals, address _mailbox) TokenRouter(_mailbox) { + _decimals = __decimals; + } + + /** + * @notice Initializes the Token router, ERC20 metadata, and mints initial supply to deployer. + * @param _totalSupply The initial supply of the token. + * @param _name The name of the token. + * @param _symbol The symbol of the token. + */ + function initialize( + uint256 _totalSupply, + string memory _name, + string memory _symbol, + address _hook, + address _interchainSecurityModule, + address _owner + ) external initializer { + // Initialize ERC20 metadata + __ERC20_init(_name, _symbol); + _mint(msg.sender, _totalSupply); + _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); + } + + function decimals() public view override returns (uint8) { + return _decimals; + } + + function balanceOf( + address _account + ) + public + view + virtual + override(TokenRouter, ERC20Upgradeable) + returns (uint256) + { + return ERC20Upgradeable.balanceOf(_account); + } + + /** + * @dev Burns `_amount` of token from `msg.sender` balance. + * @inheritdoc TokenRouter + */ + function _transferFromSender( + uint256 _amount + ) internal override returns (bytes memory) { + _burn(msg.sender, _amount); + return bytes(""); // no metadata + } + + /** + * @dev Mints `_amount` of token to `_recipient` balance. + * @inheritdoc TokenRouter + */ + function _transferTo( + address _recipient, + uint256 _amount, + bytes calldata // no metadata + ) internal virtual override { + _mint(_recipient, _amount); + } +} diff --git a/src/tokens/ERC20Collateral.sol b/src/tokens/ERC20Collateral.sol new file mode 100755 index 0000000..2128d99 --- /dev/null +++ b/src/tokens/ERC20Collateral.sol @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {TokenRouter} from "./libs/TokenRouter.sol"; +import {TokenMessage} from "./libs/TokenMessage.sol"; +import {MailboxClient} from "../client/MailboxClient.sol"; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +/** + * @title ERC20 Token Collateral that wraps an existing ERC20 with remote transfer functionality. + * @author Abacus Works + */ +contract HypERC20Collateral is TokenRouter { + using SafeERC20 for IERC20; + + IERC20 public immutable wrappedToken; + + /** + * @notice Constructor + * @param erc20 Address of the token to keep as collateral + */ + constructor(address erc20, address _mailbox) TokenRouter(_mailbox) { + wrappedToken = IERC20(erc20); + } + + function initialize( + address _hook, + address _interchainSecurityModule, + address _owner + ) public virtual initializer { + _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); + } + + function balanceOf( + address _account + ) external view override returns (uint256) { + return wrappedToken.balanceOf(_account); + } + + /** + * @dev Transfers `_amount` of `wrappedToken` from `msg.sender` to this contract. + * @inheritdoc TokenRouter + */ + function _transferFromSender( + uint256 _amount + ) internal virtual override returns (bytes memory) { + wrappedToken.safeTransferFrom(msg.sender, address(this), _amount); + return bytes(""); // no metadata + } + + /** + * @dev Transfers `_amount` of `wrappedToken` from this contract to `_recipient`. + * @inheritdoc TokenRouter + */ + function _transferTo( + address _recipient, + uint256 _amount, + bytes calldata // no metadata + ) internal virtual override { + wrappedToken.safeTransfer(_recipient, _amount); + } +} diff --git a/src/tokens/ERC721.sol b/src/tokens/ERC721.sol new file mode 100755 index 0000000..8ac75bf --- /dev/null +++ b/src/tokens/ERC721.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {TokenRouter} from "./libs/TokenRouter.sol"; + +import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; +import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; +import {ERC721EnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; + +/** + * @title ERC721 Token Router that extends ERC721 with remote transfer functionality. + * @author Abacus Works + */ +contract HypERC721 is ERC721EnumerableUpgradeable, TokenRouter { + constructor(address _mailbox) TokenRouter(_mailbox) {} + + /** + * @notice Initializes the Token router, ERC721 metadata, and mints initial supply to deployer. + * @param _mintAmount The amount of NFTs to mint to `msg.sender`. + * @param _name The name of the token. + * @param _symbol The symbol of the token. + * @param _hook The post-dispatch hook contract. + @param _interchainSecurityModule The interchain security module contract. + @param _owner The this contract. + */ + function initialize( + uint256 _mintAmount, + string memory _name, + string memory _symbol, + address _hook, + address _interchainSecurityModule, + address _owner + ) external initializer { + _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); + __ERC721_init(_name, _symbol); + for (uint256 i = 0; i < _mintAmount; i++) { + _safeMint(msg.sender, i); + } + } + + function balanceOf( + address _account + ) + public + view + virtual + override(TokenRouter, ERC721Upgradeable, IERC721Upgradeable) + returns (uint256) + { + return ERC721Upgradeable.balanceOf(_account); + } + + /** + * @dev Asserts `msg.sender` is owner and burns `_tokenId`. + * @inheritdoc TokenRouter + */ + function _transferFromSender( + uint256 _tokenId + ) internal virtual override returns (bytes memory) { + require(ownerOf(_tokenId) == msg.sender, "!owner"); + _burn(_tokenId); + return bytes(""); // no metadata + } + + /** + * @dev Mints `_tokenId` to `_recipient`. + * @inheritdoc TokenRouter + */ + function _transferTo( + address _recipient, + uint256 _tokenId, + bytes calldata // no metadata + ) internal virtual override { + _safeMint(_recipient, _tokenId); + } +} diff --git a/src/tokens/ERC721Collateral.sol b/src/tokens/ERC721Collateral.sol new file mode 100755 index 0000000..eea5cca --- /dev/null +++ b/src/tokens/ERC721Collateral.sol @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {TokenRouter} from "./libs/TokenRouter.sol"; +import {TokenMessage} from "./libs/TokenMessage.sol"; + +import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; + +/** + * @title ERC721 Token Collateral that wraps an existing ERC721 with remote transfer functionality. + * @author Abacus Works + */ +contract HypERC721Collateral is TokenRouter { + IERC721 public immutable wrappedToken; + + /** + * @notice Constructor + * @param erc721 Address of the token to keep as collateral + */ + constructor(address erc721, address _mailbox) TokenRouter(_mailbox) { + wrappedToken = IERC721(erc721); + } + + /** + * @notice Initializes the Token router + * @param _hook The post-dispatch hook contract. + @param _interchainSecurityModule The interchain security module contract. + @param _owner The this contract. + */ + function initialize( + address _hook, + address _interchainSecurityModule, + address _owner + ) public virtual initializer { + _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); + } + + function ownerOf(uint256 _tokenId) external view returns (address) { + return IERC721(wrappedToken).ownerOf(_tokenId); + } + + /** + * @dev Returns the balance of `_account` for `wrappedToken`. + * @inheritdoc TokenRouter + */ + function balanceOf( + address _account + ) external view override returns (uint256) { + return IERC721(wrappedToken).balanceOf(_account); + } + + /** + * @dev Transfers `_tokenId` of `wrappedToken` from `msg.sender` to this contract. + * @inheritdoc TokenRouter + */ + function _transferFromSender( + uint256 _tokenId + ) internal virtual override returns (bytes memory) { + // safeTransferFrom not used here because recipient is this contract + wrappedToken.transferFrom(msg.sender, address(this), _tokenId); + return bytes(""); // no metadata + } + + /** + * @dev Transfers `_tokenId` of `wrappedToken` from this contract to `_recipient`. + * @inheritdoc TokenRouter + */ + function _transferTo( + address _recipient, + uint256 _tokenId, + bytes calldata // no metadata + ) internal override { + wrappedToken.safeTransferFrom(address(this), _recipient, _tokenId); + } +} diff --git a/src/tokens/Native.sol b/src/tokens/Native.sol new file mode 100755 index 0000000..5e11a45 --- /dev/null +++ b/src/tokens/Native.sol @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {TokenRouter} from "./libs/TokenRouter.sol"; +import {TokenMessage} from "./libs/TokenMessage.sol"; +import {Address} from "@openzeppelin/contracts/utils/Address.sol"; + +/** + * @title Native Token Router that extends ERC20 with remote transfer functionality. + * @author Abacus Works + * @dev Supply on each chain is not constant but the aggregate supply across all chains is. + */ +contract HypNative is TokenRouter { + /** + * @dev Emitted when native tokens are donated to the contract. + * @param sender The address of the sender. + * @param amount The amount of native tokens donated. + */ + event Donation(address indexed sender, uint256 amount); + + constructor(address _mailbox) TokenRouter(_mailbox) {} + + /** + * @notice Initializes the Token router + * @param _hook The post-dispatch hook contract. + @param _interchainSecurityModule The interchain security module contract. + @param _owner The this contract. + */ + function initialize( + address _hook, + address _interchainSecurityModule, + address _owner + ) public initializer { + _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); + } + + /** + * @inheritdoc TokenRouter + * @dev uses (`msg.value` - `_amount`) as hook payment and `msg.sender` as refund address. + */ + function transferRemote( + uint32 _destination, + bytes32 _recipient, + uint256 _amount + ) external payable virtual override returns (bytes32 messageId) { + require(msg.value >= _amount, "Native: amount exceeds msg.value"); + uint256 _hookPayment = msg.value - _amount; + return _transferRemote(_destination, _recipient, _amount, _hookPayment); + } + + function balanceOf( + address _account + ) external view override returns (uint256) { + return _account.balance; + } + + /** + * @inheritdoc TokenRouter + * @dev No-op because native amount is transferred in `msg.value` + * @dev Compiler will not include this in the bytecode. + */ + function _transferFromSender( + uint256 + ) internal pure override returns (bytes memory) { + return bytes(""); // no metadata + } + + /** + * @dev Sends `_amount` of native token to `_recipient` balance. + * @inheritdoc TokenRouter + */ + function _transferTo( + address _recipient, + uint256 _amount, + bytes calldata // no metadata + ) internal virtual override { + Address.sendValue(payable(_recipient), _amount); + } + + receive() external payable { + emit Donation(msg.sender, msg.value); + } +} diff --git a/src/tokens/README.md b/src/tokens/README.md new file mode 100755 index 0000000..894d94c --- /dev/null +++ b/src/tokens/README.md @@ -0,0 +1,7 @@ +# Tokens + +> [!IMPORTANT] +> Only the 'Exrtension' contracts should be used + +> [!WARNING] +> Repo under active development. Do not use in production. \ No newline at end of file diff --git a/src/tokens/extensions/FastHypERC20.sol b/src/tokens/extensions/FastHypERC20.sol new file mode 100755 index 0000000..1e9b09b --- /dev/null +++ b/src/tokens/extensions/FastHypERC20.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {HypERC20} from "../HypERC20.sol"; +import {FastTokenRouter} from "../libs/FastTokenRouter.sol"; +import {TokenRouter} from "../libs/TokenRouter.sol"; + +import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; + +/** + * @title ERC20 Token Router that extends ERC20 with remote transfer functionality. + * @author Abacus Works + * @dev Supply on each chain is not constant but the aggregate supply across all chains is. + */ +contract FastHypERC20 is FastTokenRouter, HypERC20 { + constructor( + uint8 __decimals, + address _mailbox + ) HypERC20(__decimals, _mailbox) {} + + /** + * @dev delegates transfer logic to `_transferTo`. + * @inheritdoc TokenRouter + */ + function _handle( + uint32 _origin, + bytes32 _sender, + bytes calldata _message + ) internal virtual override(FastTokenRouter, TokenRouter) { + FastTokenRouter._handle(_origin, _sender, _message); + } + + /** + * @dev Mints `_amount` of tokens to `_recipient`. + * @inheritdoc FastTokenRouter + */ + function _fastTransferTo( + address _recipient, + uint256 _amount + ) internal override { + _mint(_recipient, _amount); + } + + /** + * @dev Burns `_amount` of tokens from `_recipient`. + * @inheritdoc FastTokenRouter + */ + function _fastRecieveFrom( + address _sender, + uint256 _amount + ) internal override { + _burn(_sender, _amount); + } + + function balanceOf( + address _account + ) public view virtual override(HypERC20, TokenRouter) returns (uint256) { + return ERC20Upgradeable.balanceOf(_account); + } +} diff --git a/src/tokens/extensions/FastHypERC20Collateral.sol b/src/tokens/extensions/FastHypERC20Collateral.sol new file mode 100755 index 0000000..e8d53a6 --- /dev/null +++ b/src/tokens/extensions/FastHypERC20Collateral.sol @@ -0,0 +1,60 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {HypERC20Collateral} from "../HypERC20Collateral.sol"; +import {FastTokenRouter} from "../libs/FastTokenRouter.sol"; +import {TokenRouter} from "../libs/TokenRouter.sol"; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; + +/** + * @title ERC20 Token Collateral that wraps an existing ERC20 with remote transfer functionality. + * @author Abacus Works + */ +contract FastHypERC20Collateral is FastTokenRouter, HypERC20Collateral { + using SafeERC20 for IERC20; + + /** + * @notice Constructor + * @param erc20 Address of the token to keep as collateral + */ + constructor( + address erc20, + address _mailbox + ) HypERC20Collateral(erc20, _mailbox) {} + + /** + * @dev delegates transfer logic to `_transferTo`. + * @inheritdoc FastTokenRouter + */ + function _handle( + uint32 _origin, + bytes32 _sender, + bytes calldata _message + ) internal virtual override(FastTokenRouter, TokenRouter) { + FastTokenRouter._handle(_origin, _sender, _message); + } + + /** + * @dev Transfers `_amount` of `wrappedToken` to `_recipient`. + * @inheritdoc FastTokenRouter + */ + function _fastTransferTo( + address _recipient, + uint256 _amount + ) internal override { + wrappedToken.safeTransfer(_recipient, _amount); + } + + /** + * @dev Transfers in `_amount` of `wrappedToken` from `_recipient`. + * @inheritdoc FastTokenRouter + */ + function _fastRecieveFrom( + address _sender, + uint256 _amount + ) internal override { + wrappedToken.safeTransferFrom(_sender, address(this), _amount); + } +} diff --git a/src/tokens/extensions/HypERC4626.sol b/src/tokens/extensions/HypERC4626.sol new file mode 100755 index 0000000..acdab03 --- /dev/null +++ b/src/tokens/extensions/HypERC4626.sol @@ -0,0 +1,102 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.8.0; + +import {IXERC20} from "../interfaces/IXERC20.sol"; +import {HypERC20} from "../HypERC20.sol"; +import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; +import {Message} from "../../libs/Message.sol"; +import {TokenMessage} from "../libs/TokenMessage.sol"; +import {TokenRouter} from "../libs/TokenRouter.sol"; + +/** + * @title ERC20 Rebasing Token + * @author Abacus Works + */ +contract HypERC4626 is HypERC20 { + using Math for uint256; + using Message for bytes; + using TokenMessage for bytes; + + uint256 public constant PRECISION = 1e10; + uint32 public immutable collateralDomain; + uint256 public exchangeRate; // 1e10 + + constructor( + uint8 _decimals, + address _mailbox, + uint32 _collateralDomain + ) HypERC20(_decimals, _mailbox) { + collateralDomain = _collateralDomain; + exchangeRate = 1e10; + _disableInitializers(); + } + + /// Override to send shares instead of assets from synthetic + /// @inheritdoc TokenRouter + function _transferRemote( + uint32 _destination, + bytes32 _recipient, + uint256 _amountOrId, + uint256 _value, + bytes memory _hookMetadata, + address _hook + ) internal virtual override returns (bytes32 messageId) { + uint256 _shares = assetsToShares(_amountOrId); + _transferFromSender(_shares); + bytes memory _tokenMessage = TokenMessage.format( + _recipient, + _shares, + bytes("") + ); + + messageId = _Router_dispatch( + _destination, + _value, + _tokenMessage, + _hookMetadata, + _hook + ); + + emit SentTransferRemote(_destination, _recipient, _amountOrId); + } + + function _handle( + uint32 _origin, + bytes32 _sender, + bytes calldata _message + ) internal virtual override { + if (_origin == collateralDomain) { + exchangeRate = abi.decode(_message.metadata(), (uint256)); + } + super._handle(_origin, _sender, _message); + } + + // Override to send shares locally instead of assets + function transfer( + address to, + uint256 amount + ) public virtual override returns (bool) { + address owner = _msgSender(); + _transfer(owner, to, assetsToShares(amount)); + return true; + } + + function shareBalanceOf(address account) public view returns (uint256) { + return super.balanceOf(account); + } + + function balanceOf( + address account + ) public view virtual override returns (uint256) { + uint256 _balance = super.balanceOf(account); + return sharesToAssets(_balance); + } + + function assetsToShares(uint256 _amount) public view returns (uint256) { + return _amount.mulDiv(PRECISION, exchangeRate); + } + + function sharesToAssets(uint256 _shares) public view returns (uint256) { + return _shares.mulDiv(exchangeRate, PRECISION); + } +} diff --git a/src/tokens/extensions/HypERC4626Collateral.sol b/src/tokens/extensions/HypERC4626Collateral.sol new file mode 100755 index 0000000..645db49 --- /dev/null +++ b/src/tokens/extensions/HypERC4626Collateral.sol @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; +import {TokenMessage} from "../libs/TokenMessage.sol"; +import {HypERC20Collateral} from "../HypERC20Collateral.sol"; +import {TypeCasts} from "../../libs/TypeCasts.sol"; + +/** + * @title ERC4626 Token Collateral with deposits collateral to a vault + * @author Abacus Works + */ +contract HypERC4626Collateral is HypERC20Collateral { + using TypeCasts for address; + using TokenMessage for bytes; + using Math for uint256; + + // Address of the ERC4626 compatible vault + ERC4626 public immutable vault; + uint256 public constant PRECISION = 1e10; + bytes32 public constant NULL_RECIPIENT = + 0x0000000000000000000000000000000000000000000000000000000000000001; + + constructor( + ERC4626 _vault, + address _mailbox + ) HypERC20Collateral(_vault.asset(), _mailbox) { + vault = _vault; + } + + function initialize( + address _hook, + address _interchainSecurityModule, + address _owner + ) public override initializer { + _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); + } + + function _transferRemote( + uint32 _destination, + bytes32 _recipient, + uint256 _amount, + uint256 _value, + bytes memory _hookMetadata, + address _hook + ) internal virtual override returns (bytes32 messageId) { + // Can't override _transferFromSender only because we need to pass shares in the token message + _transferFromSender(_amount); + uint256 _shares = _depositIntoVault(_amount); + uint256 _exchangeRate = PRECISION.mulDiv( + vault.totalAssets(), + vault.totalSupply(), + Math.Rounding.Down + ); + bytes memory _tokenMetadata = abi.encode(_exchangeRate); + + bytes memory _tokenMessage = TokenMessage.format( + _recipient, + _shares, + _tokenMetadata + ); + + messageId = _Router_dispatch( + _destination, + _value, + _tokenMessage, + _hookMetadata, + _hook + ); + + emit SentTransferRemote(_destination, _recipient, _shares); + } + + /** + * @dev Deposits into the vault and increment assetDeposited + * @param _amount amount to deposit into vault + */ + function _depositIntoVault(uint256 _amount) internal returns (uint256) { + wrappedToken.approve(address(vault), _amount); + return vault.deposit(_amount, address(this)); + } + + /** + * @dev Transfers `_amount` of `wrappedToken` from this contract to `_recipient`, and withdraws from vault + * @inheritdoc HypERC20Collateral + */ + function _transferTo( + address _recipient, + uint256 _amount, + bytes calldata + ) internal virtual override { + // withdraw with the specified amount of shares + vault.redeem(_amount, _recipient, address(this)); + } + + /** + * @dev Update the exchange rate on the synthetic token by accounting for additional yield accrued to the underlying vault + * @param _destinationDomain domain of the vault + */ + function rebase(uint32 _destinationDomain) public payable { + // force a rebase with an empty transfer to 0x1 + _transferRemote( + _destinationDomain, + NULL_RECIPIENT, + 0, + msg.value, + bytes(""), + address(0) + ); + } +} diff --git a/src/tokens/extensions/HypERC4626OwnerCollateral.sol b/src/tokens/extensions/HypERC4626OwnerCollateral.sol new file mode 100755 index 0000000..34c9f6e --- /dev/null +++ b/src/tokens/extensions/HypERC4626OwnerCollateral.sol @@ -0,0 +1,91 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; +import {HypERC20Collateral} from "../HypERC20Collateral.sol"; + +/** + * @title ERC20 Token Collateral with deposits collateral to a vault, the yield goes to the owner + * @author ltyu + */ +contract HypERC4626OwnerCollateral is HypERC20Collateral { + // Address of the ERC4626 compatible vault + ERC4626 public immutable vault; + + // Internal balance of total asset deposited + uint256 public assetDeposited; + + event ExcessSharesSwept(uint256 amount, uint256 assetsRedeemed); + + constructor( + ERC4626 _vault, + address _mailbox + ) HypERC20Collateral(_vault.asset(), _mailbox) { + vault = _vault; + } + + function initialize( + address _hook, + address _interchainSecurityModule, + address _owner + ) public override initializer { + wrappedToken.approve(address(vault), type(uint256).max); + _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); + } + + /** + * @dev Transfers `_amount` of `wrappedToken` from `msg.sender` to this contract, and deposit into vault + * @inheritdoc HypERC20Collateral + */ + function _transferFromSender( + uint256 _amount + ) internal override returns (bytes memory metadata) { + metadata = super._transferFromSender(_amount); + _depositIntoVault(_amount); + } + + /** + * @dev Deposits into the vault and increment assetDeposited + * @param _amount amount to deposit into vault + */ + function _depositIntoVault(uint256 _amount) internal { + assetDeposited += _amount; + vault.deposit(_amount, address(this)); + } + + /** + * @dev Transfers `_amount` of `wrappedToken` from this contract to `_recipient`, and withdraws from vault + * @inheritdoc HypERC20Collateral + */ + function _transferTo( + address _recipient, + uint256 _amount, + bytes calldata + ) internal virtual override { + _withdrawFromVault(_amount, _recipient); + } + + /** + * @dev Withdraws from the vault and decrement assetDeposited + * @param _amount amount to withdraw from vault + * @param _recipient address to deposit withdrawn underlying to + */ + function _withdrawFromVault(uint256 _amount, address _recipient) internal { + assetDeposited -= _amount; + vault.withdraw(_amount, _recipient, address(this)); + } + + /** + * @notice Allows the owner to redeem excess shares + */ + function sweep() external onlyOwner { + uint256 excessShares = vault.maxRedeem(address(this)) - + vault.convertToShares(assetDeposited); + uint256 assetsRedeemed = vault.redeem( + excessShares, + owner(), + address(this) + ); + emit ExcessSharesSwept(excessShares, assetsRedeemed); + } +} diff --git a/src/tokens/extensions/HypERC721URICollateral.sol b/src/tokens/extensions/HypERC721URICollateral.sol new file mode 100755 index 0000000..d021aa5 --- /dev/null +++ b/src/tokens/extensions/HypERC721URICollateral.sol @@ -0,0 +1,35 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {HypERC721Collateral} from "../HypERC721Collateral.sol"; + +import {IERC721MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; + +/** + * @title ERC721 Token Collateral that wraps an existing ERC721 with remote transfer and URI relay functionality. + * @author Abacus Works + */ +contract HypERC721URICollateral is HypERC721Collateral { + // solhint-disable-next-line no-empty-blocks + constructor( + address erc721, + address _mailbox + ) HypERC721Collateral(erc721, _mailbox) {} + + /** + * @dev Transfers `_tokenId` of `wrappedToken` from `msg.sender` to this contract. + * @return The URI of `_tokenId` on `wrappedToken`. + * @inheritdoc HypERC721Collateral + */ + function _transferFromSender( + uint256 _tokenId + ) internal override returns (bytes memory) { + HypERC721Collateral._transferFromSender(_tokenId); + return + bytes( + IERC721MetadataUpgradeable(address(wrappedToken)).tokenURI( + _tokenId + ) + ); + } +} diff --git a/src/tokens/extensions/HypERC721URIStorage.sol b/src/tokens/extensions/HypERC721URIStorage.sol new file mode 100755 index 0000000..8dad5d4 --- /dev/null +++ b/src/tokens/extensions/HypERC721URIStorage.sol @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {HypERC721} from "../HypERC721.sol"; + +import {ERC721URIStorageUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; +import {ERC721EnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; +import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; +import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; + +/** + * @title ERC721 Token that extends ERC721URIStorage with remote transfer and URI relay functionality. + * @author Abacus Works + */ +contract HypERC721URIStorage is HypERC721, ERC721URIStorageUpgradeable { + constructor(address _mailbox) HypERC721(_mailbox) {} + + function balanceOf( + address account + ) + public + view + override(HypERC721, ERC721Upgradeable, IERC721Upgradeable) + returns (uint256) + { + return HypERC721.balanceOf(account); + } + + /** + * @return _tokenURI The URI of `_tokenId`. + * @inheritdoc HypERC721 + */ + function _transferFromSender( + uint256 _tokenId + ) internal override returns (bytes memory _tokenURI) { + _tokenURI = bytes(tokenURI(_tokenId)); // requires minted + HypERC721._transferFromSender(_tokenId); + } + + /** + * @dev Sets the URI for `_tokenId` to `_tokenURI`. + * @inheritdoc HypERC721 + */ + function _transferTo( + address _recipient, + uint256 _tokenId, + bytes calldata _tokenURI + ) internal override { + HypERC721._transferTo(_recipient, _tokenId, _tokenURI); + _setTokenURI(_tokenId, string(_tokenURI)); // requires minted + } + + function tokenURI( + uint256 tokenId + ) + public + view + override(ERC721Upgradeable, ERC721URIStorageUpgradeable) + returns (string memory) + { + return ERC721URIStorageUpgradeable.tokenURI(tokenId); + } + + function _beforeTokenTransfer( + address from, + address to, + uint256 tokenId, + uint256 batchSize + ) internal override(ERC721EnumerableUpgradeable, ERC721Upgradeable) { + ERC721EnumerableUpgradeable._beforeTokenTransfer( + from, + to, + tokenId, + batchSize + ); + } + + function supportsInterface( + bytes4 interfaceId + ) + public + view + override(ERC721EnumerableUpgradeable, ERC721URIStorageUpgradeable) + returns (bool) + { + return ERC721EnumerableUpgradeable.supportsInterface(interfaceId); + } + + function _burn( + uint256 tokenId + ) internal override(ERC721URIStorageUpgradeable, ERC721Upgradeable) { + ERC721URIStorageUpgradeable._burn(tokenId); + } +} diff --git a/src/tokens/extensions/HypFiatToken.sol b/src/tokens/extensions/HypFiatToken.sol new file mode 100755 index 0000000..c31351a --- /dev/null +++ b/src/tokens/extensions/HypFiatToken.sol @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.8.0; + +import {IFiatToken} from "../interfaces/IFiatToken.sol"; +import {HypERC20Collateral} from "../HypERC20Collateral.sol"; + +// see https://github.com/circlefin/stablecoin-evm/blob/master/doc/tokendesign.md#issuing-and-destroying-tokens +contract HypFiatToken is HypERC20Collateral { + constructor( + address _fiatToken, + address _mailbox + ) HypERC20Collateral(_fiatToken, _mailbox) {} + + function _transferFromSender( + uint256 _amount + ) internal override returns (bytes memory metadata) { + // transfer amount to address(this) + metadata = super._transferFromSender(_amount); + // burn amount of address(this) balance + IFiatToken(address(wrappedToken)).burn(_amount); + } + + function _transferTo( + address _recipient, + uint256 _amount, + bytes calldata /*metadata*/ + ) internal override { + require( + IFiatToken(address(wrappedToken)).mint(_recipient, _amount), + "FiatToken mint failed" + ); + } +} diff --git a/src/tokens/extensions/HypNativeScaled.sol b/src/tokens/extensions/HypNativeScaled.sol new file mode 100755 index 0000000..2aa0b71 --- /dev/null +++ b/src/tokens/extensions/HypNativeScaled.sol @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {HypNative} from "../HypNative.sol"; +import {TokenRouter} from "../libs/TokenRouter.sol"; + +/** + * @title Native Token that scales native value by a fixed factor for consistency with other tokens. + * @dev The scale factor multiplies the `message.amount` to the local native token amount. + * Conversely, it divides the local native `msg.value` amount by `scale` to encode the `message.amount`. + * @author Abacus Works + */ +contract HypNativeScaled is HypNative { + uint256 public immutable scale; + + constructor(uint256 _scale, address _mailbox) HypNative(_mailbox) { + scale = _scale; + } + + /** + * @inheritdoc HypNative + * @dev Sends scaled `msg.value` (divided by `scale`) to `_recipient`. + */ + function transferRemote( + uint32 _destination, + bytes32 _recipient, + uint256 _amount + ) external payable override returns (bytes32 messageId) { + require(msg.value >= _amount, "Native: amount exceeds msg.value"); + uint256 _hookPayment = msg.value - _amount; + uint256 _scaledAmount = _amount / scale; + return + _transferRemote( + _destination, + _recipient, + _scaledAmount, + _hookPayment + ); + } + + /** + * @dev Sends scaled `_amount` (multiplied by `scale`) to `_recipient`. + * @inheritdoc TokenRouter + */ + function _transferTo( + address _recipient, + uint256 _amount, + bytes calldata metadata // no metadata + ) internal override { + uint256 scaledAmount = _amount * scale; + HypNative._transferTo(_recipient, scaledAmount, metadata); + } +} diff --git a/src/tokens/extensions/HypXERC20.sol b/src/tokens/extensions/HypXERC20.sol new file mode 100755 index 0000000..84ab7a8 --- /dev/null +++ b/src/tokens/extensions/HypXERC20.sol @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.8.0; + +import {IXERC20} from "../interfaces/IXERC20.sol"; +import {HypERC20Collateral} from "../HypERC20Collateral.sol"; + +contract HypXERC20 is HypERC20Collateral { + constructor( + address _xerc20, + address _mailbox + ) HypERC20Collateral(_xerc20, _mailbox) { + _disableInitializers(); + } + + function _transferFromSender( + uint256 _amountOrId + ) internal override returns (bytes memory metadata) { + IXERC20(address(wrappedToken)).burn(msg.sender, _amountOrId); + return ""; + } + + function _transferTo( + address _recipient, + uint256 _amountOrId, + bytes calldata /*metadata*/ + ) internal override { + IXERC20(address(wrappedToken)).mint(_recipient, _amountOrId); + } +} diff --git a/src/tokens/extensions/HypXERC20Lockbox.sol b/src/tokens/extensions/HypXERC20Lockbox.sol new file mode 100755 index 0000000..f2c26e7 --- /dev/null +++ b/src/tokens/extensions/HypXERC20Lockbox.sol @@ -0,0 +1,76 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.8.0; + +import {IXERC20Lockbox} from "../interfaces/IXERC20Lockbox.sol"; +import {IXERC20, IERC20} from "../interfaces/IXERC20.sol"; +import {HypERC20Collateral} from "../HypERC20Collateral.sol"; + +contract HypXERC20Lockbox is HypERC20Collateral { + uint256 constant MAX_INT = 2 ** 256 - 1; + + IXERC20Lockbox public immutable lockbox; + IXERC20 public immutable xERC20; + + constructor( + address _lockbox, + address _mailbox + ) HypERC20Collateral(address(IXERC20Lockbox(_lockbox).ERC20()), _mailbox) { + lockbox = IXERC20Lockbox(_lockbox); + xERC20 = lockbox.XERC20(); + approveLockbox(); + _disableInitializers(); + } + + /** + * @notice Approve the lockbox to spend the wrapped token and xERC20 + * @dev This function is idempotent and need not be access controlled + */ + function approveLockbox() public { + require( + IERC20(wrappedToken).approve(address(lockbox), MAX_INT), + "erc20 lockbox approve failed" + ); + require( + xERC20.approve(address(lockbox), MAX_INT), + "xerc20 lockbox approve failed" + ); + } + + /** + * @notice Initialize the contract + * @param _hook The address of the hook contract + * @param _ism The address of the interchain security module + * @param _owner The address of the owner + */ + function initialize( + address _hook, + address _ism, + address _owner + ) public override initializer { + approveLockbox(); + _MailboxClient_initialize(_hook, _ism, _owner); + } + + function _transferFromSender( + uint256 _amount + ) internal override returns (bytes memory) { + // transfer erc20 from sender + super._transferFromSender(_amount); + // convert erc20 to xERC20 + lockbox.deposit(_amount); + // burn xERC20 + xERC20.burn(address(this), _amount); + return bytes(""); + } + + function _transferTo( + address _recipient, + uint256 _amount, + bytes calldata /*metadata*/ + ) internal override { + // mint xERC20 + xERC20.mint(address(this), _amount); + // convert xERC20 to erc20 + lockbox.withdrawTo(_recipient, _amount); + } +} diff --git a/src/tokens/interfaces/IFiatToken.sol b/src/tokens/interfaces/IFiatToken.sol new file mode 100755 index 0000000..11a5afa --- /dev/null +++ b/src/tokens/interfaces/IFiatToken.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +// adapted from https://github.com/circlefin/stablecoin-evm +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +interface IFiatToken is IERC20 { + /** + * @notice Allows a minter to burn some of its own tokens. + * @dev The caller must be a minter, must not be blacklisted, and the amount to burn + * should be less than or equal to the account's balance. + * @param _amount the amount of tokens to be burned. + */ + function burn(uint256 _amount) external; + + /** + * @notice Mints fiat tokens to an address. + * @param _to The address that will receive the minted tokens. + * @param _amount The amount of tokens to mint. Must be less than or equal + * to the minterAllowance of the caller. + * @return True if the operation was successful. + */ + function mint(address _to, uint256 _amount) external returns (bool); +} diff --git a/src/tokens/interfaces/IXERC20.sol b/src/tokens/interfaces/IXERC20.sol new file mode 100755 index 0000000..b933af1 --- /dev/null +++ b/src/tokens/interfaces/IXERC20.sol @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.0; + +// adapted from https://github.com/defi-wonderland/xERC20 + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +interface IXERC20 is IERC20 { + /** + * @notice Mints tokens for a user + * @dev Can only be called by a minter + * @param _user The address of the user who needs tokens minted + * @param _amount The amount of tokens being minted + */ + function mint(address _user, uint256 _amount) external; + + /** + * @notice Burns tokens for a user + * @dev Can only be called by a minter + * @param _user The address of the user who needs tokens burned + * @param _amount The amount of tokens being burned + */ + function burn(address _user, uint256 _amount) external; + + /** + * @notice Updates the limits of any bridge + * @dev Can only be called by the owner + * @param _mintingLimit The updated minting limit we are setting to the bridge + * @param _burningLimit The updated burning limit we are setting to the bridge + * @param _bridge The address of the bridge we are setting the limits too + */ + function setLimits( + address _bridge, + uint256 _mintingLimit, + uint256 _burningLimit + ) external; + + function owner() external returns (address); + + /** + * @notice Returns the current limit of a bridge + * @param _bridge the bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + function burningCurrentLimitOf( + address _bridge + ) external view returns (uint256 _limit); + + /** + * @notice Returns the current limit of a bridge + * @param _bridge the bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + function mintingCurrentLimitOf( + address _bridge + ) external view returns (uint256 _limit); + + /** + * @notice Returns the max limit of a minter + * + * @param _minter The minter we are viewing the limits of + * @return _limit The limit the minter has + */ + function mintingMaxLimitOf( + address _minter + ) external view returns (uint256 _limit); + + /** + * @notice Returns the max limit of a bridge + * + * @param _bridge the bridge we are viewing the limits of + * @return _limit The limit the bridge has + */ + + function burningMaxLimitOf( + address _bridge + ) external view returns (uint256 _limit); +} diff --git a/src/tokens/interfaces/IXERC20Lockbox.sol b/src/tokens/interfaces/IXERC20Lockbox.sol new file mode 100755 index 0000000..ba01f7b --- /dev/null +++ b/src/tokens/interfaces/IXERC20Lockbox.sol @@ -0,0 +1,61 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity >=0.8.4 <0.9.0; + +// adapted from https://github.com/defi-wonderland/xERC20 + +import {IXERC20} from "./IXERC20.sol"; +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +interface IXERC20Lockbox { + /** + * @notice The XERC20 token of this contract + */ + function XERC20() external returns (IXERC20); + + /** + * @notice The ERC20 token of this contract + */ + function ERC20() external returns (IERC20); + + /** + * @notice Deposit ERC20 tokens into the lockbox + * + * @param _amount The amount of tokens to deposit + */ + + function deposit(uint256 _amount) external; + + /** + * @notice Deposit ERC20 tokens into the lockbox, and send the XERC20 to a user + * + * @param _user The user to send the XERC20 to + * @param _amount The amount of tokens to deposit + */ + + function depositTo(address _user, uint256 _amount) external; + + /** + * @notice Deposit the native asset into the lockbox, and send the XERC20 to a user + * + * @param _user The user to send the XERC20 to + */ + + function depositNativeTo(address _user) external payable; + + /** + * @notice Withdraw ERC20 tokens from the lockbox + * + * @param _amount The amount of tokens to withdraw + */ + + function withdraw(uint256 _amount) external; + + /** + * @notice Withdraw ERC20 tokens from the lockbox + * + * @param _user The user to withdraw to + * @param _amount The amount of tokens to withdraw + */ + + function withdrawTo(address _user, uint256 _amount) external; +} diff --git a/src/tokens/libs/FastTokenRouter.sol b/src/tokens/libs/FastTokenRouter.sol new file mode 100755 index 0000000..8e4418a --- /dev/null +++ b/src/tokens/libs/FastTokenRouter.sol @@ -0,0 +1,210 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {TypeCasts} from "../../libs/TypeCasts.sol"; + +import {TokenMessage} from "./TokenMessage.sol"; +import {TokenRouter} from "./TokenRouter.sol"; + +/** + * @title Common FastTokenRouter functionality for ERC20 Tokens with remote transfer support. + * @author Abacus Works + */ +abstract contract FastTokenRouter is TokenRouter { + using TypeCasts for bytes32; + using TokenMessage for bytes; + + uint256 public fastTransferId; + // maps `fastTransferId` to the filler address. + mapping(bytes32 => address) filledFastTransfers; + + /** + * @dev delegates transfer logic to `_transferTo`. + * @inheritdoc TokenRouter + */ + function _handle( + uint32 _origin, + bytes32, + bytes calldata _message + ) internal virtual override { + bytes32 recipient = _message.recipient(); + uint256 amount = _message.amount(); + bytes calldata metadata = _message.metadata(); + _transferTo(recipient.bytes32ToAddress(), amount, _origin, metadata); + emit ReceivedTransferRemote(_origin, recipient, amount); + } + + /** + * @dev Transfers `_amount` of token to `_recipient`/`fastFiller` who provided LP. + * @dev Called by `handle` after message decoding. + */ + function _transferTo( + address _recipient, + uint256 _amount, + uint32 _origin, + bytes calldata _metadata + ) internal virtual { + address _tokenRecipient = _getTokenRecipient( + _recipient, + _amount, + _origin, + _metadata + ); + + _fastTransferTo(_tokenRecipient, _amount); + } + + /** + * @dev allows an external user to full an unfilled fast transfer order. + * @param _recipient The recipient of the wrapped token on base chain. + * @param _amount The amount of wrapped tokens that is being bridged. + * @param _fastFee The fee the bridging entity will pay. + * @param _fastTransferId Id assigned on the remote chain to uniquely identify the transfer. + */ + function fillFastTransfer( + address _recipient, + uint256 _amount, + uint256 _fastFee, + uint32 _origin, + uint256 _fastTransferId + ) external virtual { + bytes32 filledFastTransfersKey = _getFastTransfersKey( + _origin, + _fastTransferId, + _amount, + _fastFee, + _recipient + ); + require( + filledFastTransfers[filledFastTransfersKey] == address(0), + "request already filled" + ); + + filledFastTransfers[filledFastTransfersKey] = msg.sender; + + _fastRecieveFrom(msg.sender, _amount - _fastFee); + _fastTransferTo(_recipient, _amount - _fastFee); + } + + /** + * @dev Transfers `_amountOrId` token to `_recipient` on `_destination` domain. + * @dev Delegates transfer logic to `_fastTransferFromSender` implementation. + * @dev Emits `SentTransferRemote` event on the origin chain. + * @param _destination The identifier of the destination chain. + * @param _recipient The address of the recipient on the destination chain. + * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient. + * @return messageId The identifier of the dispatched message. + */ + function fastTransferRemote( + uint32 _destination, + bytes32 _recipient, + uint256 _amountOrId, + uint256 _fastFee + ) public payable virtual returns (bytes32 messageId) { + uint256 _fastTransferId = fastTransferId + 1; + fastTransferId = _fastTransferId; + bytes memory metadata = _fastTransferFromSender( + _amountOrId, + _fastFee, + _fastTransferId + ); + + messageId = _GasRouter_dispatch( + _destination, + msg.value, + TokenMessage.format(_recipient, _amountOrId, metadata), + address(hook) + ); + emit SentTransferRemote(_destination, _recipient, _amountOrId); + } + + /** + * @dev Burns `_amount` of token from `msg.sender` balance. + * @dev Pays `_fastFee` of tokens to LP on source chain. + * @dev Returns `fastFee` as bytes in the form of metadata. + */ + function _fastTransferFromSender( + uint256 _amount, + uint256 _fastFee, + uint256 _fastTransferId + ) internal virtual returns (bytes memory) { + _fastRecieveFrom(msg.sender, _amount); + return abi.encode(_fastFee, _fastTransferId); + } + + /** + * @dev returns an address that indicates who should receive the bridged tokens. + * @dev if _fastFees was included and someone filled the order before the mailbox made the contract call, the filler gets the funds. + */ + function _getTokenRecipient( + address _recipient, + uint256 _amount, + uint32 _origin, + bytes calldata _metadata + ) internal view returns (address) { + if (_metadata.length == 0) { + return _recipient; + } + + // decode metadata to extract `_fastFee` and `_fastTransferId`. + (uint256 _fastFee, uint256 _fastTransferId) = abi.decode( + _metadata, + (uint256, uint256) + ); + + address _fillerAddress = filledFastTransfers[ + _getFastTransfersKey( + _origin, + _fastTransferId, + _amount, + _fastFee, + _recipient + ) + ]; + if (_fillerAddress != address(0)) { + return _fillerAddress; + } + + return _recipient; + } + + /** + * @dev generates the key for storing the filler address of fast transfers. + */ + function _getFastTransfersKey( + uint32 _origin, + uint256 _fastTransferId, + uint256 _amount, + uint256 _fastFee, + address _recipient + ) internal pure returns (bytes32) { + return + keccak256( + abi.encodePacked( + _origin, + _fastTransferId, + _amount, + _fastFee, + _recipient + ) + ); + } + + /** + * @dev Should transfer `_amount` of tokens to `_recipient`. + * @dev The implementation is delegated. + */ + function _fastTransferTo( + address _recipient, + uint256 _amount + ) internal virtual; + + /** + * @dev Should collect `amount` of tokens from `_sender`. + * @dev The implementation is delegated. + */ + function _fastRecieveFrom( + address _sender, + uint256 _amount + ) internal virtual; +} diff --git a/src/tokens/libs/TokenMessage.sol b/src/tokens/libs/TokenMessage.sol new file mode 100755 index 0000000..d593b1e --- /dev/null +++ b/src/tokens/libs/TokenMessage.sol @@ -0,0 +1,31 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.8.0; + +library TokenMessage { + function format( + bytes32 _recipient, + uint256 _amount, + bytes memory _metadata + ) internal pure returns (bytes memory) { + return abi.encodePacked(_recipient, _amount, _metadata); + } + + function recipient(bytes calldata message) internal pure returns (bytes32) { + return bytes32(message[0:32]); + } + + function amount(bytes calldata message) internal pure returns (uint256) { + return uint256(bytes32(message[32:64])); + } + + // alias for ERC721 + function tokenId(bytes calldata message) internal pure returns (uint256) { + return amount(message); + } + + function metadata( + bytes calldata message + ) internal pure returns (bytes calldata) { + return message[64:]; + } +} diff --git a/src/tokens/libs/TokenRouter.sol b/src/tokens/libs/TokenRouter.sol new file mode 100755 index 0000000..6d8d761 --- /dev/null +++ b/src/tokens/libs/TokenRouter.sol @@ -0,0 +1,180 @@ +// SPDX-License-Identifier: Apache-2.0 +pragma solidity >=0.8.0; + +import {IPostDispatchHook} from "../../interfaces/hooks/IPostDispatchHook.sol"; +import {GasRouter} from "../../client/GasRouter.sol"; +import {MailboxClient} from "../../client/MailboxClient.sol"; +import {TypeCasts} from "../../libs/TypeCasts.sol"; +import {TokenMessage} from "./TokenMessage.sol"; + +/** + * @title Native Token Router that extends Router with abstract token (ERC20/ERC721) remote transfer functionality. + * @author Abacus Works + */ +abstract contract TokenRouter is GasRouter { + using TypeCasts for bytes32; + using TypeCasts for address; + using TokenMessage for bytes; + + /** + * @dev Emitted on `transferRemote` when a transfer message is dispatched. + * @param destination The identifier of the destination chain. + * @param recipient The address of the recipient on the destination chain. + * @param amount The amount of tokens burnt on the origin chain. + */ + event SentTransferRemote( + uint32 indexed destination, + bytes32 indexed recipient, + uint256 amount + ); + + /** + * @dev Emitted on `_handle` when a transfer message is processed. + * @param origin The identifier of the origin chain. + * @param recipient The address of the recipient on the destination chain. + * @param amount The amount of tokens minted on the destination chain. + */ + event ReceivedTransferRemote( + uint32 indexed origin, + bytes32 indexed recipient, + uint256 amount + ); + + constructor(address _mailbox) GasRouter(_mailbox) {} + + /** + * @notice Transfers `_amountOrId` token to `_recipient` on `_destination` domain. + * @dev Delegates transfer logic to `_transferFromSender` implementation. + * @dev Emits `SentTransferRemote` event on the origin chain. + * @param _destination The identifier of the destination chain. + * @param _recipient The address of the recipient on the destination chain. + * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient. + * @return messageId The identifier of the dispatched message. + */ + function transferRemote( + uint32 _destination, + bytes32 _recipient, + uint256 _amountOrId + ) external payable virtual returns (bytes32 messageId) { + return + _transferRemote(_destination, _recipient, _amountOrId, msg.value); + } + + /** + * @notice Transfers `_amountOrId` token to `_recipient` on `_destination` domain with a specified hook + * @dev Delegates transfer logic to `_transferFromSender` implementation. + * @dev The metadata is the token metadata, and is DIFFERENT than the hook metadata. + * @dev Emits `SentTransferRemote` event on the origin chain. + * @param _destination The identifier of the destination chain. + * @param _recipient The address of the recipient on the destination chain. + * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient. + * @param _hookMetadata The metadata passed into the hook + * @param _hook The post dispatch hook to be called by the Mailbox + * @return messageId The identifier of the dispatched message. + */ + function transferRemote( + uint32 _destination, + bytes32 _recipient, + uint256 _amountOrId, + bytes calldata _hookMetadata, + address _hook + ) external payable virtual returns (bytes32 messageId) { + return + _transferRemote( + _destination, + _recipient, + _amountOrId, + msg.value, + _hookMetadata, + _hook + ); + } + + function _transferRemote( + uint32 _destination, + bytes32 _recipient, + uint256 _amountOrId, + uint256 _value + ) internal returns (bytes32 messageId) { + return + _transferRemote( + _destination, + _recipient, + _amountOrId, + _value, + _GasRouter_hookMetadata(_destination), + address(hook) + ); + } + + function _transferRemote( + uint32 _destination, + bytes32 _recipient, + uint256 _amountOrId, + uint256 _value, + bytes memory _hookMetadata, + address _hook + ) internal virtual returns (bytes32 messageId) { + bytes memory _tokenMetadata = _transferFromSender(_amountOrId); + bytes memory _tokenMessage = TokenMessage.format( + _recipient, + _amountOrId, + _tokenMetadata + ); + + messageId = _Router_dispatch( + _destination, + _value, + _tokenMessage, + _hookMetadata, + _hook + ); + + emit SentTransferRemote(_destination, _recipient, _amountOrId); + } + + /** + * @dev Should transfer `_amountOrId` of tokens from `msg.sender` to this token router. + * @dev Called by `transferRemote` before message dispatch. + * @dev Optionally returns `metadata` associated with the transfer to be passed in message. + */ + function _transferFromSender( + uint256 _amountOrId + ) internal virtual returns (bytes memory metadata); + + /** + * @notice Returns the balance of `account` on this token router. + * @param account The address to query the balance of. + * @return The balance of `account`. + */ + function balanceOf(address account) external virtual returns (uint256); + + /** + * @dev Mints tokens to recipient when router receives transfer message. + * @dev Emits `ReceivedTransferRemote` event on the destination chain. + * @param _origin The identifier of the origin chain. + * @param _message The encoded remote transfer message containing the recipient address and amount. + */ + function _handle( + uint32 _origin, + bytes32, + bytes calldata _message + ) internal virtual override { + bytes32 recipient = _message.recipient(); + uint256 amount = _message.amount(); + bytes calldata metadata = _message.metadata(); + _transferTo(recipient.bytes32ToAddress(), amount, metadata); + emit ReceivedTransferRemote(_origin, recipient, amount); + } + + /** + * @dev Should transfer `_amountOrId` of tokens from this token router to `_recipient`. + * @dev Called by `handle` after message decoding. + * @dev Optionally handles `metadata` associated with transfer passed in message. + */ + function _transferTo( + address _recipient, + uint256 _amountOrId, + bytes calldata metadata + ) internal virtual; +} From cfd5013c4dd20e43b7703dcb7431f1dc7f1d1acb Mon Sep 17 00:00:00 2001 From: sam bacha Date: Thu, 15 Aug 2024 22:34:20 -0700 Subject: [PATCH 2/8] feat(lido): init support rebasing --- src/tokens/ERC20.sol | 78 -------------- src/tokens/ERC20Collateral.sol | 64 ------------ src/tokens/ERC721.sol | 76 -------------- src/tokens/ERC721Collateral.sol | 75 ------------- src/tokens/libs/TokenRouter.sol | 180 -------------------------------- 5 files changed, 473 deletions(-) delete mode 100755 src/tokens/ERC20.sol delete mode 100755 src/tokens/ERC20Collateral.sol delete mode 100755 src/tokens/ERC721.sol delete mode 100755 src/tokens/ERC721Collateral.sol delete mode 100755 src/tokens/libs/TokenRouter.sol diff --git a/src/tokens/ERC20.sol b/src/tokens/ERC20.sol deleted file mode 100755 index be63c05..0000000 --- a/src/tokens/ERC20.sol +++ /dev/null @@ -1,78 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity >=0.8.0; - -import {TokenRouter} from "./libs/TokenRouter.sol"; - -import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; - -/** - * @title ERC20 Token Router that extends ERC20 with remote transfer functionality. - * @author Abacus Works - * @dev Supply on each chain is not constant but the aggregate supply across all chains is. - */ -contract HypERC20 is ERC20Upgradeable, TokenRouter { - uint8 private immutable _decimals; - - constructor(uint8 __decimals, address _mailbox) TokenRouter(_mailbox) { - _decimals = __decimals; - } - - /** - * @notice Initializes the Token router, ERC20 metadata, and mints initial supply to deployer. - * @param _totalSupply The initial supply of the token. - * @param _name The name of the token. - * @param _symbol The symbol of the token. - */ - function initialize( - uint256 _totalSupply, - string memory _name, - string memory _symbol, - address _hook, - address _interchainSecurityModule, - address _owner - ) external initializer { - // Initialize ERC20 metadata - __ERC20_init(_name, _symbol); - _mint(msg.sender, _totalSupply); - _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); - } - - function decimals() public view override returns (uint8) { - return _decimals; - } - - function balanceOf( - address _account - ) - public - view - virtual - override(TokenRouter, ERC20Upgradeable) - returns (uint256) - { - return ERC20Upgradeable.balanceOf(_account); - } - - /** - * @dev Burns `_amount` of token from `msg.sender` balance. - * @inheritdoc TokenRouter - */ - function _transferFromSender( - uint256 _amount - ) internal override returns (bytes memory) { - _burn(msg.sender, _amount); - return bytes(""); // no metadata - } - - /** - * @dev Mints `_amount` of token to `_recipient` balance. - * @inheritdoc TokenRouter - */ - function _transferTo( - address _recipient, - uint256 _amount, - bytes calldata // no metadata - ) internal virtual override { - _mint(_recipient, _amount); - } -} diff --git a/src/tokens/ERC20Collateral.sol b/src/tokens/ERC20Collateral.sol deleted file mode 100755 index 2128d99..0000000 --- a/src/tokens/ERC20Collateral.sol +++ /dev/null @@ -1,64 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity >=0.8.0; - -import {TokenRouter} from "./libs/TokenRouter.sol"; -import {TokenMessage} from "./libs/TokenMessage.sol"; -import {MailboxClient} from "../client/MailboxClient.sol"; - -import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; -import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; - -/** - * @title ERC20 Token Collateral that wraps an existing ERC20 with remote transfer functionality. - * @author Abacus Works - */ -contract HypERC20Collateral is TokenRouter { - using SafeERC20 for IERC20; - - IERC20 public immutable wrappedToken; - - /** - * @notice Constructor - * @param erc20 Address of the token to keep as collateral - */ - constructor(address erc20, address _mailbox) TokenRouter(_mailbox) { - wrappedToken = IERC20(erc20); - } - - function initialize( - address _hook, - address _interchainSecurityModule, - address _owner - ) public virtual initializer { - _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); - } - - function balanceOf( - address _account - ) external view override returns (uint256) { - return wrappedToken.balanceOf(_account); - } - - /** - * @dev Transfers `_amount` of `wrappedToken` from `msg.sender` to this contract. - * @inheritdoc TokenRouter - */ - function _transferFromSender( - uint256 _amount - ) internal virtual override returns (bytes memory) { - wrappedToken.safeTransferFrom(msg.sender, address(this), _amount); - return bytes(""); // no metadata - } - - /** - * @dev Transfers `_amount` of `wrappedToken` from this contract to `_recipient`. - * @inheritdoc TokenRouter - */ - function _transferTo( - address _recipient, - uint256 _amount, - bytes calldata // no metadata - ) internal virtual override { - wrappedToken.safeTransfer(_recipient, _amount); - } -} diff --git a/src/tokens/ERC721.sol b/src/tokens/ERC721.sol deleted file mode 100755 index 8ac75bf..0000000 --- a/src/tokens/ERC721.sol +++ /dev/null @@ -1,76 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity >=0.8.0; - -import {TokenRouter} from "./libs/TokenRouter.sol"; - -import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; -import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; -import {ERC721EnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; - -/** - * @title ERC721 Token Router that extends ERC721 with remote transfer functionality. - * @author Abacus Works - */ -contract HypERC721 is ERC721EnumerableUpgradeable, TokenRouter { - constructor(address _mailbox) TokenRouter(_mailbox) {} - - /** - * @notice Initializes the Token router, ERC721 metadata, and mints initial supply to deployer. - * @param _mintAmount The amount of NFTs to mint to `msg.sender`. - * @param _name The name of the token. - * @param _symbol The symbol of the token. - * @param _hook The post-dispatch hook contract. - @param _interchainSecurityModule The interchain security module contract. - @param _owner The this contract. - */ - function initialize( - uint256 _mintAmount, - string memory _name, - string memory _symbol, - address _hook, - address _interchainSecurityModule, - address _owner - ) external initializer { - _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); - __ERC721_init(_name, _symbol); - for (uint256 i = 0; i < _mintAmount; i++) { - _safeMint(msg.sender, i); - } - } - - function balanceOf( - address _account - ) - public - view - virtual - override(TokenRouter, ERC721Upgradeable, IERC721Upgradeable) - returns (uint256) - { - return ERC721Upgradeable.balanceOf(_account); - } - - /** - * @dev Asserts `msg.sender` is owner and burns `_tokenId`. - * @inheritdoc TokenRouter - */ - function _transferFromSender( - uint256 _tokenId - ) internal virtual override returns (bytes memory) { - require(ownerOf(_tokenId) == msg.sender, "!owner"); - _burn(_tokenId); - return bytes(""); // no metadata - } - - /** - * @dev Mints `_tokenId` to `_recipient`. - * @inheritdoc TokenRouter - */ - function _transferTo( - address _recipient, - uint256 _tokenId, - bytes calldata // no metadata - ) internal virtual override { - _safeMint(_recipient, _tokenId); - } -} diff --git a/src/tokens/ERC721Collateral.sol b/src/tokens/ERC721Collateral.sol deleted file mode 100755 index eea5cca..0000000 --- a/src/tokens/ERC721Collateral.sol +++ /dev/null @@ -1,75 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity >=0.8.0; - -import {TokenRouter} from "./libs/TokenRouter.sol"; -import {TokenMessage} from "./libs/TokenMessage.sol"; - -import {IERC721} from "@openzeppelin/contracts/token/ERC721/IERC721.sol"; - -/** - * @title ERC721 Token Collateral that wraps an existing ERC721 with remote transfer functionality. - * @author Abacus Works - */ -contract HypERC721Collateral is TokenRouter { - IERC721 public immutable wrappedToken; - - /** - * @notice Constructor - * @param erc721 Address of the token to keep as collateral - */ - constructor(address erc721, address _mailbox) TokenRouter(_mailbox) { - wrappedToken = IERC721(erc721); - } - - /** - * @notice Initializes the Token router - * @param _hook The post-dispatch hook contract. - @param _interchainSecurityModule The interchain security module contract. - @param _owner The this contract. - */ - function initialize( - address _hook, - address _interchainSecurityModule, - address _owner - ) public virtual initializer { - _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); - } - - function ownerOf(uint256 _tokenId) external view returns (address) { - return IERC721(wrappedToken).ownerOf(_tokenId); - } - - /** - * @dev Returns the balance of `_account` for `wrappedToken`. - * @inheritdoc TokenRouter - */ - function balanceOf( - address _account - ) external view override returns (uint256) { - return IERC721(wrappedToken).balanceOf(_account); - } - - /** - * @dev Transfers `_tokenId` of `wrappedToken` from `msg.sender` to this contract. - * @inheritdoc TokenRouter - */ - function _transferFromSender( - uint256 _tokenId - ) internal virtual override returns (bytes memory) { - // safeTransferFrom not used here because recipient is this contract - wrappedToken.transferFrom(msg.sender, address(this), _tokenId); - return bytes(""); // no metadata - } - - /** - * @dev Transfers `_tokenId` of `wrappedToken` from this contract to `_recipient`. - * @inheritdoc TokenRouter - */ - function _transferTo( - address _recipient, - uint256 _tokenId, - bytes calldata // no metadata - ) internal override { - wrappedToken.safeTransferFrom(address(this), _recipient, _tokenId); - } -} diff --git a/src/tokens/libs/TokenRouter.sol b/src/tokens/libs/TokenRouter.sol deleted file mode 100755 index 6d8d761..0000000 --- a/src/tokens/libs/TokenRouter.sol +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity >=0.8.0; - -import {IPostDispatchHook} from "../../interfaces/hooks/IPostDispatchHook.sol"; -import {GasRouter} from "../../client/GasRouter.sol"; -import {MailboxClient} from "../../client/MailboxClient.sol"; -import {TypeCasts} from "../../libs/TypeCasts.sol"; -import {TokenMessage} from "./TokenMessage.sol"; - -/** - * @title Native Token Router that extends Router with abstract token (ERC20/ERC721) remote transfer functionality. - * @author Abacus Works - */ -abstract contract TokenRouter is GasRouter { - using TypeCasts for bytes32; - using TypeCasts for address; - using TokenMessage for bytes; - - /** - * @dev Emitted on `transferRemote` when a transfer message is dispatched. - * @param destination The identifier of the destination chain. - * @param recipient The address of the recipient on the destination chain. - * @param amount The amount of tokens burnt on the origin chain. - */ - event SentTransferRemote( - uint32 indexed destination, - bytes32 indexed recipient, - uint256 amount - ); - - /** - * @dev Emitted on `_handle` when a transfer message is processed. - * @param origin The identifier of the origin chain. - * @param recipient The address of the recipient on the destination chain. - * @param amount The amount of tokens minted on the destination chain. - */ - event ReceivedTransferRemote( - uint32 indexed origin, - bytes32 indexed recipient, - uint256 amount - ); - - constructor(address _mailbox) GasRouter(_mailbox) {} - - /** - * @notice Transfers `_amountOrId` token to `_recipient` on `_destination` domain. - * @dev Delegates transfer logic to `_transferFromSender` implementation. - * @dev Emits `SentTransferRemote` event on the origin chain. - * @param _destination The identifier of the destination chain. - * @param _recipient The address of the recipient on the destination chain. - * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient. - * @return messageId The identifier of the dispatched message. - */ - function transferRemote( - uint32 _destination, - bytes32 _recipient, - uint256 _amountOrId - ) external payable virtual returns (bytes32 messageId) { - return - _transferRemote(_destination, _recipient, _amountOrId, msg.value); - } - - /** - * @notice Transfers `_amountOrId` token to `_recipient` on `_destination` domain with a specified hook - * @dev Delegates transfer logic to `_transferFromSender` implementation. - * @dev The metadata is the token metadata, and is DIFFERENT than the hook metadata. - * @dev Emits `SentTransferRemote` event on the origin chain. - * @param _destination The identifier of the destination chain. - * @param _recipient The address of the recipient on the destination chain. - * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient. - * @param _hookMetadata The metadata passed into the hook - * @param _hook The post dispatch hook to be called by the Mailbox - * @return messageId The identifier of the dispatched message. - */ - function transferRemote( - uint32 _destination, - bytes32 _recipient, - uint256 _amountOrId, - bytes calldata _hookMetadata, - address _hook - ) external payable virtual returns (bytes32 messageId) { - return - _transferRemote( - _destination, - _recipient, - _amountOrId, - msg.value, - _hookMetadata, - _hook - ); - } - - function _transferRemote( - uint32 _destination, - bytes32 _recipient, - uint256 _amountOrId, - uint256 _value - ) internal returns (bytes32 messageId) { - return - _transferRemote( - _destination, - _recipient, - _amountOrId, - _value, - _GasRouter_hookMetadata(_destination), - address(hook) - ); - } - - function _transferRemote( - uint32 _destination, - bytes32 _recipient, - uint256 _amountOrId, - uint256 _value, - bytes memory _hookMetadata, - address _hook - ) internal virtual returns (bytes32 messageId) { - bytes memory _tokenMetadata = _transferFromSender(_amountOrId); - bytes memory _tokenMessage = TokenMessage.format( - _recipient, - _amountOrId, - _tokenMetadata - ); - - messageId = _Router_dispatch( - _destination, - _value, - _tokenMessage, - _hookMetadata, - _hook - ); - - emit SentTransferRemote(_destination, _recipient, _amountOrId); - } - - /** - * @dev Should transfer `_amountOrId` of tokens from `msg.sender` to this token router. - * @dev Called by `transferRemote` before message dispatch. - * @dev Optionally returns `metadata` associated with the transfer to be passed in message. - */ - function _transferFromSender( - uint256 _amountOrId - ) internal virtual returns (bytes memory metadata); - - /** - * @notice Returns the balance of `account` on this token router. - * @param account The address to query the balance of. - * @return The balance of `account`. - */ - function balanceOf(address account) external virtual returns (uint256); - - /** - * @dev Mints tokens to recipient when router receives transfer message. - * @dev Emits `ReceivedTransferRemote` event on the destination chain. - * @param _origin The identifier of the origin chain. - * @param _message The encoded remote transfer message containing the recipient address and amount. - */ - function _handle( - uint32 _origin, - bytes32, - bytes calldata _message - ) internal virtual override { - bytes32 recipient = _message.recipient(); - uint256 amount = _message.amount(); - bytes calldata metadata = _message.metadata(); - _transferTo(recipient.bytes32ToAddress(), amount, metadata); - emit ReceivedTransferRemote(_origin, recipient, amount); - } - - /** - * @dev Should transfer `_amountOrId` of tokens from this token router to `_recipient`. - * @dev Called by `handle` after message decoding. - * @dev Optionally handles `metadata` associated with transfer passed in message. - */ - function _transferTo( - address _recipient, - uint256 _amountOrId, - bytes calldata metadata - ) internal virtual; -} From 4ade497f84aa91c262f15abb203f25ce6030a160 Mon Sep 17 00:00:00 2001 From: sam bacha Date: Thu, 15 Aug 2024 22:36:57 -0700 Subject: [PATCH 3/8] refactor(libs): extenstions overhaul --- src/tokens/Native.sol | 2 +- .../{FastHypERC20.sol => ManifoldERC20.sol} | 8 ++++---- ...lateral.sol => ManifoldERC20Collateral.sol} | 6 +++--- .../{HypERC4626.sol => ManifoldERC4626.sol} | 6 +++--- ...teral.sol => ManifoldERC4626Collateral.sol} | 8 ++++---- ....sol => ManifoldERC4626OwnerCollateral.sol} | 10 +++++----- ...ral.sol => ManifoldERC721URICollateral.sol} | 10 +++++----- ...torage.sol => ManifoldERC721URIStorage.sol} | 18 +++++++++--------- ...{HypFiatToken.sol => ManifoldFiatToken.sol} | 6 +++--- ...tiveScaled.sol => ManifoldNativeScaled.sol} | 10 +++++----- .../{HypXERC20.sol => ManifoldXERC20.sol} | 6 +++--- ...20Lockbox.sol => ManifoldXERC20Lockbox.sol} | 6 +++--- 12 files changed, 48 insertions(+), 48 deletions(-) rename src/tokens/extensions/{FastHypERC20.sol => ManifoldERC20.sol} (86%) rename src/tokens/extensions/{FastHypERC20Collateral.sol => ManifoldERC20Collateral.sol} (88%) rename src/tokens/extensions/{HypERC4626.sol => ManifoldERC4626.sol} (95%) rename src/tokens/extensions/{HypERC4626Collateral.sol => ManifoldERC4626Collateral.sol} (93%) rename src/tokens/extensions/{HypERC4626OwnerCollateral.sol => ManifoldERC4626OwnerCollateral.sol} (90%) rename src/tokens/extensions/{HypERC721URICollateral.sol => ManifoldERC721URICollateral.sol} (75%) rename src/tokens/extensions/{HypERC721URIStorage.sol => ManifoldERC721URIStorage.sol} (82%) rename src/tokens/extensions/{HypFiatToken.sol => ManifoldFiatToken.sol} (83%) rename src/tokens/extensions/{HypNativeScaled.sol => ManifoldNativeScaled.sol} (83%) rename src/tokens/extensions/{HypXERC20.sol => ManifoldXERC20.sol} (79%) rename src/tokens/extensions/{HypXERC20Lockbox.sol => ManifoldXERC20Lockbox.sol} (90%) diff --git a/src/tokens/Native.sol b/src/tokens/Native.sol index 5e11a45..7637c0f 100755 --- a/src/tokens/Native.sol +++ b/src/tokens/Native.sol @@ -10,7 +10,7 @@ import {Address} from "@openzeppelin/contracts/utils/Address.sol"; * @author Abacus Works * @dev Supply on each chain is not constant but the aggregate supply across all chains is. */ -contract HypNative is TokenRouter { +contract ManifoldNative is TokenRouter { /** * @dev Emitted when native tokens are donated to the contract. * @param sender The address of the sender. diff --git a/src/tokens/extensions/FastHypERC20.sol b/src/tokens/extensions/ManifoldERC20.sol similarity index 86% rename from src/tokens/extensions/FastHypERC20.sol rename to src/tokens/extensions/ManifoldERC20.sol index 1e9b09b..098a52a 100755 --- a/src/tokens/extensions/FastHypERC20.sol +++ b/src/tokens/extensions/ManifoldERC20.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0; -import {HypERC20} from "../HypERC20.sol"; +import {ManifoldERC20} from "../ManifoldERC20.sol"; import {FastTokenRouter} from "../libs/FastTokenRouter.sol"; import {TokenRouter} from "../libs/TokenRouter.sol"; @@ -12,11 +12,11 @@ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ * @author Abacus Works * @dev Supply on each chain is not constant but the aggregate supply across all chains is. */ -contract FastHypERC20 is FastTokenRouter, HypERC20 { +contract FastManifoldERC20 is FastTokenRouter, ManifoldERC20 { constructor( uint8 __decimals, address _mailbox - ) HypERC20(__decimals, _mailbox) {} + ) ManifoldERC20(__decimals, _mailbox) {} /** * @dev delegates transfer logic to `_transferTo`. @@ -54,7 +54,7 @@ contract FastHypERC20 is FastTokenRouter, HypERC20 { function balanceOf( address _account - ) public view virtual override(HypERC20, TokenRouter) returns (uint256) { + ) public view virtual override(ManifoldERC20, TokenRouter) returns (uint256) { return ERC20Upgradeable.balanceOf(_account); } } diff --git a/src/tokens/extensions/FastHypERC20Collateral.sol b/src/tokens/extensions/ManifoldERC20Collateral.sol similarity index 88% rename from src/tokens/extensions/FastHypERC20Collateral.sol rename to src/tokens/extensions/ManifoldERC20Collateral.sol index e8d53a6..b134ccb 100755 --- a/src/tokens/extensions/FastHypERC20Collateral.sol +++ b/src/tokens/extensions/ManifoldERC20Collateral.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0; -import {HypERC20Collateral} from "../HypERC20Collateral.sol"; +import {ManifoldERC20Collateral} from "../ManifoldERC20Collateral.sol"; import {FastTokenRouter} from "../libs/FastTokenRouter.sol"; import {TokenRouter} from "../libs/TokenRouter.sol"; @@ -12,7 +12,7 @@ import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol * @title ERC20 Token Collateral that wraps an existing ERC20 with remote transfer functionality. * @author Abacus Works */ -contract FastHypERC20Collateral is FastTokenRouter, HypERC20Collateral { +contract FastManifoldERC20Collateral is FastTokenRouter, ManifoldERC20Collateral { using SafeERC20 for IERC20; /** @@ -22,7 +22,7 @@ contract FastHypERC20Collateral is FastTokenRouter, HypERC20Collateral { constructor( address erc20, address _mailbox - ) HypERC20Collateral(erc20, _mailbox) {} + ) ManifoldERC20Collateral(erc20, _mailbox) {} /** * @dev delegates transfer logic to `_transferTo`. diff --git a/src/tokens/extensions/HypERC4626.sol b/src/tokens/extensions/ManifoldERC4626.sol similarity index 95% rename from src/tokens/extensions/HypERC4626.sol rename to src/tokens/extensions/ManifoldERC4626.sol index acdab03..7c69196 100755 --- a/src/tokens/extensions/HypERC4626.sol +++ b/src/tokens/extensions/ManifoldERC4626.sol @@ -2,7 +2,7 @@ pragma solidity >=0.8.0; import {IXERC20} from "../interfaces/IXERC20.sol"; -import {HypERC20} from "../HypERC20.sol"; +import {ManifoldERC20} from "../ManifoldERC20.sol"; import {Math} from "@openzeppelin/contracts/utils/math/Math.sol"; import {Message} from "../../libs/Message.sol"; import {TokenMessage} from "../libs/TokenMessage.sol"; @@ -12,7 +12,7 @@ import {TokenRouter} from "../libs/TokenRouter.sol"; * @title ERC20 Rebasing Token * @author Abacus Works */ -contract HypERC4626 is HypERC20 { +contract ManifoldERC4626 is ManifoldERC20 { using Math for uint256; using Message for bytes; using TokenMessage for bytes; @@ -25,7 +25,7 @@ contract HypERC4626 is HypERC20 { uint8 _decimals, address _mailbox, uint32 _collateralDomain - ) HypERC20(_decimals, _mailbox) { + ) ManifoldERC20(_decimals, _mailbox) { collateralDomain = _collateralDomain; exchangeRate = 1e10; _disableInitializers(); diff --git a/src/tokens/extensions/HypERC4626Collateral.sol b/src/tokens/extensions/ManifoldERC4626Collateral.sol similarity index 93% rename from src/tokens/extensions/HypERC4626Collateral.sol rename to src/tokens/extensions/ManifoldERC4626Collateral.sol index 645db49..a5b5b79 100755 --- a/src/tokens/extensions/HypERC4626Collateral.sol +++ b/src/tokens/extensions/ManifoldERC4626Collateral.sol @@ -3,14 +3,14 @@ pragma solidity >=0.8.0; import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; import {TokenMessage} from "../libs/TokenMessage.sol"; -import {HypERC20Collateral} from "../HypERC20Collateral.sol"; +import {ManifoldERC20Collateral} from "../ManifoldERC20Collateral.sol"; import {TypeCasts} from "../../libs/TypeCasts.sol"; /** * @title ERC4626 Token Collateral with deposits collateral to a vault * @author Abacus Works */ -contract HypERC4626Collateral is HypERC20Collateral { +contract ManifoldERC4626Collateral is ManifoldERC20Collateral { using TypeCasts for address; using TokenMessage for bytes; using Math for uint256; @@ -24,7 +24,7 @@ contract HypERC4626Collateral is HypERC20Collateral { constructor( ERC4626 _vault, address _mailbox - ) HypERC20Collateral(_vault.asset(), _mailbox) { + ) ManifoldERC20Collateral(_vault.asset(), _mailbox) { vault = _vault; } @@ -82,7 +82,7 @@ contract HypERC4626Collateral is HypERC20Collateral { /** * @dev Transfers `_amount` of `wrappedToken` from this contract to `_recipient`, and withdraws from vault - * @inheritdoc HypERC20Collateral + * @inheritdoc ManifoldERC20Collateral */ function _transferTo( address _recipient, diff --git a/src/tokens/extensions/HypERC4626OwnerCollateral.sol b/src/tokens/extensions/ManifoldERC4626OwnerCollateral.sol similarity index 90% rename from src/tokens/extensions/HypERC4626OwnerCollateral.sol rename to src/tokens/extensions/ManifoldERC4626OwnerCollateral.sol index 34c9f6e..93ce6b9 100755 --- a/src/tokens/extensions/HypERC4626OwnerCollateral.sol +++ b/src/tokens/extensions/ManifoldERC4626OwnerCollateral.sol @@ -2,13 +2,13 @@ pragma solidity >=0.8.0; import "@openzeppelin/contracts/token/ERC20/extensions/ERC4626.sol"; -import {HypERC20Collateral} from "../HypERC20Collateral.sol"; +import {ManifoldERC20Collateral} from "../ManifoldERC20Collateral.sol"; /** * @title ERC20 Token Collateral with deposits collateral to a vault, the yield goes to the owner * @author ltyu */ -contract HypERC4626OwnerCollateral is HypERC20Collateral { +contract ManifoldERC4626OwnerCollateral is ManifoldERC20Collateral { // Address of the ERC4626 compatible vault ERC4626 public immutable vault; @@ -20,7 +20,7 @@ contract HypERC4626OwnerCollateral is HypERC20Collateral { constructor( ERC4626 _vault, address _mailbox - ) HypERC20Collateral(_vault.asset(), _mailbox) { + ) ManifoldERC20Collateral(_vault.asset(), _mailbox) { vault = _vault; } @@ -35,7 +35,7 @@ contract HypERC4626OwnerCollateral is HypERC20Collateral { /** * @dev Transfers `_amount` of `wrappedToken` from `msg.sender` to this contract, and deposit into vault - * @inheritdoc HypERC20Collateral + * @inheritdoc ManifoldERC20Collateral */ function _transferFromSender( uint256 _amount @@ -55,7 +55,7 @@ contract HypERC4626OwnerCollateral is HypERC20Collateral { /** * @dev Transfers `_amount` of `wrappedToken` from this contract to `_recipient`, and withdraws from vault - * @inheritdoc HypERC20Collateral + * @inheritdoc ManifoldERC20Collateral */ function _transferTo( address _recipient, diff --git a/src/tokens/extensions/HypERC721URICollateral.sol b/src/tokens/extensions/ManifoldERC721URICollateral.sol similarity index 75% rename from src/tokens/extensions/HypERC721URICollateral.sol rename to src/tokens/extensions/ManifoldERC721URICollateral.sol index d021aa5..ca05d4a 100755 --- a/src/tokens/extensions/HypERC721URICollateral.sol +++ b/src/tokens/extensions/ManifoldERC721URICollateral.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0; -import {HypERC721Collateral} from "../HypERC721Collateral.sol"; +import {ManifoldERC721Collateral} from "../ManifoldERC721Collateral.sol"; import {IERC721MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; @@ -9,22 +9,22 @@ import {IERC721MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/to * @title ERC721 Token Collateral that wraps an existing ERC721 with remote transfer and URI relay functionality. * @author Abacus Works */ -contract HypERC721URICollateral is HypERC721Collateral { +contract ManifoldERC721URICollateral is ManifoldERC721Collateral { // solhint-disable-next-line no-empty-blocks constructor( address erc721, address _mailbox - ) HypERC721Collateral(erc721, _mailbox) {} + ) ManifoldERC721Collateral(erc721, _mailbox) {} /** * @dev Transfers `_tokenId` of `wrappedToken` from `msg.sender` to this contract. * @return The URI of `_tokenId` on `wrappedToken`. - * @inheritdoc HypERC721Collateral + * @inheritdoc ManifoldERC721Collateral */ function _transferFromSender( uint256 _tokenId ) internal override returns (bytes memory) { - HypERC721Collateral._transferFromSender(_tokenId); + ManifoldERC721Collateral._transferFromSender(_tokenId); return bytes( IERC721MetadataUpgradeable(address(wrappedToken)).tokenURI( diff --git a/src/tokens/extensions/HypERC721URIStorage.sol b/src/tokens/extensions/ManifoldERC721URIStorage.sol similarity index 82% rename from src/tokens/extensions/HypERC721URIStorage.sol rename to src/tokens/extensions/ManifoldERC721URIStorage.sol index 8dad5d4..c5886b3 100755 --- a/src/tokens/extensions/HypERC721URIStorage.sol +++ b/src/tokens/extensions/ManifoldERC721URIStorage.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0; -import {HypERC721} from "../HypERC721.sol"; +import {ManifoldERC721} from "../ManifoldERC721.sol"; import {ERC721URIStorageUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; import {ERC721EnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; @@ -12,41 +12,41 @@ import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC7 * @title ERC721 Token that extends ERC721URIStorage with remote transfer and URI relay functionality. * @author Abacus Works */ -contract HypERC721URIStorage is HypERC721, ERC721URIStorageUpgradeable { - constructor(address _mailbox) HypERC721(_mailbox) {} +contract ManifoldERC721URIStorage is ManifoldERC721, ERC721URIStorageUpgradeable { + constructor(address _mailbox) ManifoldERC721(_mailbox) {} function balanceOf( address account ) public view - override(HypERC721, ERC721Upgradeable, IERC721Upgradeable) + override(ManifoldERC721, ERC721Upgradeable, IERC721Upgradeable) returns (uint256) { - return HypERC721.balanceOf(account); + return ManifoldERC721.balanceOf(account); } /** * @return _tokenURI The URI of `_tokenId`. - * @inheritdoc HypERC721 + * @inheritdoc ManifoldERC721 */ function _transferFromSender( uint256 _tokenId ) internal override returns (bytes memory _tokenURI) { _tokenURI = bytes(tokenURI(_tokenId)); // requires minted - HypERC721._transferFromSender(_tokenId); + ManifoldERC721._transferFromSender(_tokenId); } /** * @dev Sets the URI for `_tokenId` to `_tokenURI`. - * @inheritdoc HypERC721 + * @inheritdoc ManifoldERC721 */ function _transferTo( address _recipient, uint256 _tokenId, bytes calldata _tokenURI ) internal override { - HypERC721._transferTo(_recipient, _tokenId, _tokenURI); + ManifoldERC721._transferTo(_recipient, _tokenId, _tokenURI); _setTokenURI(_tokenId, string(_tokenURI)); // requires minted } diff --git a/src/tokens/extensions/HypFiatToken.sol b/src/tokens/extensions/ManifoldFiatToken.sol similarity index 83% rename from src/tokens/extensions/HypFiatToken.sol rename to src/tokens/extensions/ManifoldFiatToken.sol index c31351a..3f6a0ee 100755 --- a/src/tokens/extensions/HypFiatToken.sol +++ b/src/tokens/extensions/ManifoldFiatToken.sol @@ -2,14 +2,14 @@ pragma solidity >=0.8.0; import {IFiatToken} from "../interfaces/IFiatToken.sol"; -import {HypERC20Collateral} from "../HypERC20Collateral.sol"; +import {ManifoldERC20Collateral} from "../ManifoldERC20Collateral.sol"; // see https://github.com/circlefin/stablecoin-evm/blob/master/doc/tokendesign.md#issuing-and-destroying-tokens -contract HypFiatToken is HypERC20Collateral { +contract ManifoldFiatToken is ManifoldERC20Collateral { constructor( address _fiatToken, address _mailbox - ) HypERC20Collateral(_fiatToken, _mailbox) {} + ) ManifoldERC20Collateral(_fiatToken, _mailbox) {} function _transferFromSender( uint256 _amount diff --git a/src/tokens/extensions/HypNativeScaled.sol b/src/tokens/extensions/ManifoldNativeScaled.sol similarity index 83% rename from src/tokens/extensions/HypNativeScaled.sol rename to src/tokens/extensions/ManifoldNativeScaled.sol index 2aa0b71..647d0b4 100755 --- a/src/tokens/extensions/HypNativeScaled.sol +++ b/src/tokens/extensions/ManifoldNativeScaled.sol @@ -1,7 +1,7 @@ // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.8.0; -import {HypNative} from "../HypNative.sol"; +import {ManifoldNative} from "../ManifoldNative.sol"; import {TokenRouter} from "../libs/TokenRouter.sol"; /** @@ -10,15 +10,15 @@ import {TokenRouter} from "../libs/TokenRouter.sol"; * Conversely, it divides the local native `msg.value` amount by `scale` to encode the `message.amount`. * @author Abacus Works */ -contract HypNativeScaled is HypNative { +contract ManifoldNativeScaled is ManifoldNative { uint256 public immutable scale; - constructor(uint256 _scale, address _mailbox) HypNative(_mailbox) { + constructor(uint256 _scale, address _mailbox) ManifoldNative(_mailbox) { scale = _scale; } /** - * @inheritdoc HypNative + * @inheritdoc ManifoldNative * @dev Sends scaled `msg.value` (divided by `scale`) to `_recipient`. */ function transferRemote( @@ -48,6 +48,6 @@ contract HypNativeScaled is HypNative { bytes calldata metadata // no metadata ) internal override { uint256 scaledAmount = _amount * scale; - HypNative._transferTo(_recipient, scaledAmount, metadata); + ManifoldNative._transferTo(_recipient, scaledAmount, metadata); } } diff --git a/src/tokens/extensions/HypXERC20.sol b/src/tokens/extensions/ManifoldXERC20.sol similarity index 79% rename from src/tokens/extensions/HypXERC20.sol rename to src/tokens/extensions/ManifoldXERC20.sol index 84ab7a8..4fff1be 100755 --- a/src/tokens/extensions/HypXERC20.sol +++ b/src/tokens/extensions/ManifoldXERC20.sol @@ -2,13 +2,13 @@ pragma solidity >=0.8.0; import {IXERC20} from "../interfaces/IXERC20.sol"; -import {HypERC20Collateral} from "../HypERC20Collateral.sol"; +import {ManifoldERC20Collateral} from "../ManifoldERC20Collateral.sol"; -contract HypXERC20 is HypERC20Collateral { +contract ManifoldXERC20 is ManifoldERC20Collateral { constructor( address _xerc20, address _mailbox - ) HypERC20Collateral(_xerc20, _mailbox) { + ) ManifoldERC20Collateral(_xerc20, _mailbox) { _disableInitializers(); } diff --git a/src/tokens/extensions/HypXERC20Lockbox.sol b/src/tokens/extensions/ManifoldXERC20Lockbox.sol similarity index 90% rename from src/tokens/extensions/HypXERC20Lockbox.sol rename to src/tokens/extensions/ManifoldXERC20Lockbox.sol index f2c26e7..2dc7164 100755 --- a/src/tokens/extensions/HypXERC20Lockbox.sol +++ b/src/tokens/extensions/ManifoldXERC20Lockbox.sol @@ -3,9 +3,9 @@ pragma solidity >=0.8.0; import {IXERC20Lockbox} from "../interfaces/IXERC20Lockbox.sol"; import {IXERC20, IERC20} from "../interfaces/IXERC20.sol"; -import {HypERC20Collateral} from "../HypERC20Collateral.sol"; +import {ManifoldERC20Collateral} from "../ManifoldERC20Collateral.sol"; -contract HypXERC20Lockbox is HypERC20Collateral { +contract ManifoldXERC20Lockbox is ManifoldERC20Collateral { uint256 constant MAX_INT = 2 ** 256 - 1; IXERC20Lockbox public immutable lockbox; @@ -14,7 +14,7 @@ contract HypXERC20Lockbox is HypERC20Collateral { constructor( address _lockbox, address _mailbox - ) HypERC20Collateral(address(IXERC20Lockbox(_lockbox).ERC20()), _mailbox) { + ) ManifoldERC20Collateral(address(IXERC20Lockbox(_lockbox).ERC20()), _mailbox) { lockbox = IXERC20Lockbox(_lockbox); xERC20 = lockbox.XERC20(); approveLockbox(); From 48d367d5fda081aa5882529fcb347eaf2faf6063 Mon Sep 17 00:00:00 2001 From: sam bacha Date: Thu, 15 Aug 2024 22:37:12 -0700 Subject: [PATCH 4/8] fix(fmt): lint apply --- src/interfaces/IDelegationManager.sol | 19 ++- .../IECDSAStakeRegistryEventsAndErrors.sol | 16 +-- src/interfaces/IGasOracle.sol | 7 +- src/interfaces/IInterchainGasPaymaster.sol | 21 +--- src/interfaces/IInterchainSecurityModule.sol | 10 +- .../ILiquidityLayerMessageRecipient.sol | 9 +- src/interfaces/IMailbox.sol | 40 ++---- src/interfaces/IMessageRecipient.sol | 6 +- src/interfaces/IRouter.sol | 5 +- src/interfaces/IValidatorAnnounce.sol | 12 +- src/interfaces/hooks/IMessageDispatcher.sol | 12 +- src/interfaces/hooks/IPostDispatchHook.sol | 14 +-- src/interfaces/isms/IAggregationIsm.sol | 7 +- src/interfaces/isms/ICcipReadIsm.sol | 8 +- src/interfaces/isms/IMultisigIsm.sol | 7 +- src/interfaces/isms/IRoutingIsm.sol | 4 +- src/interfaces/isms/IWeightedMultisigIsm.sol | 5 +- .../optimism/ICrossDomainMessenger.sol | 6 +- src/tokens/Native.sol | 30 ++--- src/tokens/extensions/ManifoldERC20.sol | 29 ++--- .../extensions/ManifoldERC20Collateral.sol | 25 ++-- src/tokens/extensions/ManifoldERC4626.sol | 35 +----- .../extensions/ManifoldERC4626Collateral.sol | 49 ++------ .../ManifoldERC4626OwnerCollateral.sol | 30 +---- .../ManifoldERC721URICollateral.sol | 19 +-- .../extensions/ManifoldERC721URIStorage.sol | 49 +++----- src/tokens/extensions/ManifoldFiatToken.sol | 20 +-- .../extensions/ManifoldNativeScaled.sol | 19 ++- src/tokens/extensions/ManifoldXERC20.sol | 15 +-- .../extensions/ManifoldXERC20Lockbox.sol | 33 ++--- src/tokens/interfaces/IXERC20.sol | 23 +--- src/tokens/interfaces/IXERC20Lockbox.sol | 5 - src/tokens/libs/FastTokenRouter.sol | 117 +++++------------- src/tokens/libs/TokenMessage.sol | 10 +- 34 files changed, 188 insertions(+), 528 deletions(-) diff --git a/src/interfaces/IDelegationManager.sol b/src/interfaces/IDelegationManager.sol index 50fe929..09f651c 100755 --- a/src/interfaces/IDelegationManager.sol +++ b/src/interfaces/IDelegationManager.sol @@ -20,18 +20,13 @@ interface IDelegationManager { uint32 stakerOptOutWindowBlocks; } - event OperatorMetadataURIUpdated( - address indexed operator, - string metadataURI - ); + event OperatorMetadataURIUpdated(address indexed operator, string metadataURI); - function registerAsOperator( - OperatorDetails calldata registeringOperatorDetails, - string calldata metadataURI - ) external; + function registerAsOperator(OperatorDetails calldata registeringOperatorDetails, string calldata metadataURI) + external; - function getOperatorShares( - address operator, - IStrategy[] memory strategies - ) external view returns (uint256[] memory); + function getOperatorShares(address operator, IStrategy[] memory strategies) + external + view + returns (uint256[] memory); } diff --git a/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol b/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol index 07f6323..edaec81 100755 --- a/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol +++ b/src/interfaces/IECDSAStakeRegistryEventsAndErrors.sol @@ -36,20 +36,13 @@ interface IECDSAStakeRegistryEventsAndErrors { /// @notice Emitted when the weight required to be an operator changes /// @param oldMinimumWeight The previous weight /// @param newMinimumWeight The updated weight - event UpdateMinimumWeight( - uint256 oldMinimumWeight, - uint256 newMinimumWeight - ); + event UpdateMinimumWeight(uint256 oldMinimumWeight, uint256 newMinimumWeight); /// @notice Emitted when the system updates an operator's weight /// @param _operator The address of the operator updated /// @param oldWeight The operator's weight before the update /// @param newWeight The operator's weight after the update - event OperatorWeightUpdated( - address indexed _operator, - uint256 oldWeight, - uint256 newWeight - ); + event OperatorWeightUpdated(address indexed _operator, uint256 oldWeight, uint256 newWeight); /// @notice Emitted when the system updates the total weight /// @param oldTotalWeight The total weight before the update @@ -65,10 +58,7 @@ interface IECDSAStakeRegistryEventsAndErrors { /// @param newSigningKey The operator's signing key after the update /// @param oldSigningKey The operator's signing key before the update event SigningKeyUpdate( - address indexed operator, - uint256 indexed updateBlock, - address indexed newSigningKey, - address oldSigningKey + address indexed operator, uint256 indexed updateBlock, address indexed newSigningKey, address oldSigningKey ); /// @notice Indicates when the lengths of the signers array and signatures array do not match. diff --git a/src/interfaces/IGasOracle.sol b/src/interfaces/IGasOracle.sol index 1d4251c..e613d43 100755 --- a/src/interfaces/IGasOracle.sol +++ b/src/interfaces/IGasOracle.sol @@ -9,7 +9,8 @@ interface IGasOracle { uint128 gasPrice; } - function getExchangeRateAndGasPrice( - uint32 _destinationDomain - ) external view returns (uint128 tokenExchangeRate, uint128 gasPrice); + function getExchangeRateAndGasPrice(uint32 _destinationDomain) + external + view + returns (uint128 tokenExchangeRate, uint128 gasPrice); } diff --git a/src/interfaces/IInterchainGasPaymaster.sol b/src/interfaces/IInterchainGasPaymaster.sol index 405bd75..18997eb 100755 --- a/src/interfaces/IInterchainGasPaymaster.sol +++ b/src/interfaces/IInterchainGasPaymaster.sol @@ -14,22 +14,11 @@ interface IInterchainGasPaymaster { * @param gasAmount The amount of destination gas paid for. * @param payment The amount of native tokens paid. */ - event GasPayment( - bytes32 indexed messageId, - uint32 indexed destinationDomain, - uint256 gasAmount, - uint256 payment - ); + event GasPayment(bytes32 indexed messageId, uint32 indexed destinationDomain, uint256 gasAmount, uint256 payment); - function payForGas( - bytes32 _messageId, - uint32 _destinationDomain, - uint256 _gasAmount, - address _refundAddress - ) external payable; + function payForGas(bytes32 _messageId, uint32 _destinationDomain, uint256 _gasAmount, address _refundAddress) + external + payable; - function quoteGasPayment( - uint32 _destinationDomain, - uint256 _gasAmount - ) external view returns (uint256); + function quoteGasPayment(uint32 _destinationDomain, uint256 _gasAmount) external view returns (uint256); } diff --git a/src/interfaces/IInterchainSecurityModule.sol b/src/interfaces/IInterchainSecurityModule.sol index 3dd1c94..ccac164 100755 --- a/src/interfaces/IInterchainSecurityModule.sol +++ b/src/interfaces/IInterchainSecurityModule.sol @@ -31,15 +31,9 @@ interface IInterchainSecurityModule { * @param _message Manifold Finance AVS encoded interchain message * @return True if the message was verified */ - function verify( - bytes calldata _metadata, - bytes calldata _message - ) external returns (bool); + function verify(bytes calldata _metadata, bytes calldata _message) external returns (bool); } interface ISpecifiesInterchainSecurityModule { - function interchainSecurityModule() - external - view - returns (IInterchainSecurityModule); + function interchainSecurityModule() external view returns (IInterchainSecurityModule); } diff --git a/src/interfaces/ILiquidityLayerMessageRecipient.sol b/src/interfaces/ILiquidityLayerMessageRecipient.sol index 1fc03e3..883a3df 100755 --- a/src/interfaces/ILiquidityLayerMessageRecipient.sol +++ b/src/interfaces/ILiquidityLayerMessageRecipient.sol @@ -2,11 +2,6 @@ pragma solidity ^0.8.13; interface ILiquidityLayerMessageRecipient { - function handleWithTokens( - uint32 _origin, - bytes32 _sender, - bytes calldata _message, - address _token, - uint256 _amount - ) external; + function handleWithTokens(uint32 _origin, bytes32 _sender, bytes calldata _message, address _token, uint256 _amount) + external; } diff --git a/src/interfaces/IMailbox.sol b/src/interfaces/IMailbox.sol index 893afe6..d8b820a 100755 --- a/src/interfaces/IMailbox.sol +++ b/src/interfaces/IMailbox.sol @@ -13,12 +13,7 @@ interface IMailbox { * @param recipient The message recipient address on `destination` * @param message Raw bytes of message */ - event Dispatch( - address indexed sender, - uint32 indexed destination, - bytes32 indexed recipient, - bytes message - ); + event Dispatch(address indexed sender, uint32 indexed destination, bytes32 indexed recipient, bytes message); /** * @notice Emitted when a new message is dispatched via Manifold Finance AVS @@ -38,11 +33,7 @@ interface IMailbox { * @param sender The message sender address on `origin` * @param recipient The address that handled the message */ - event Process( - uint32 indexed origin, - bytes32 indexed sender, - address indexed recipient - ); + event Process(uint32 indexed origin, bytes32 indexed sender, address indexed recipient); function localDomain() external view returns (uint32); @@ -56,17 +47,15 @@ interface IMailbox { function latestDispatchedId() external view returns (bytes32); - function dispatch( - uint32 destinationDomain, - bytes32 recipientAddress, - bytes calldata messageBody - ) external payable returns (bytes32 messageId); + function dispatch(uint32 destinationDomain, bytes32 recipientAddress, bytes calldata messageBody) + external + payable + returns (bytes32 messageId); - function quoteDispatch( - uint32 destinationDomain, - bytes32 recipientAddress, - bytes calldata messageBody - ) external view returns (uint256 fee); + function quoteDispatch(uint32 destinationDomain, bytes32 recipientAddress, bytes calldata messageBody) + external + view + returns (uint256 fee); function dispatch( uint32 destinationDomain, @@ -98,12 +87,7 @@ interface IMailbox { IPostDispatchHook customHook ) external view returns (uint256 fee); - function process( - bytes calldata metadata, - bytes calldata message - ) external payable; + function process(bytes calldata metadata, bytes calldata message) external payable; - function recipientIsm( - address recipient - ) external view returns (IInterchainSecurityModule module); + function recipientIsm(address recipient) external view returns (IInterchainSecurityModule module); } diff --git a/src/interfaces/IMessageRecipient.sol b/src/interfaces/IMessageRecipient.sol index 187194b..910b613 100755 --- a/src/interfaces/IMessageRecipient.sol +++ b/src/interfaces/IMessageRecipient.sol @@ -2,9 +2,5 @@ pragma solidity >=0.6.11; interface IMessageRecipient { - function handle( - uint32 _origin, - bytes32 _sender, - bytes calldata _message - ) external payable; + function handle(uint32 _origin, bytes32 _sender, bytes calldata _message) external payable; } diff --git a/src/interfaces/IRouter.sol b/src/interfaces/IRouter.sol index a26020d..00df6ae 100755 --- a/src/interfaces/IRouter.sol +++ b/src/interfaces/IRouter.sol @@ -8,8 +8,5 @@ interface IRouter { function enrollRemoteRouter(uint32 _domain, bytes32 _router) external; - function enrollRemoteRouters( - uint32[] calldata _domains, - bytes32[] calldata _routers - ) external; + function enrollRemoteRouters(uint32[] calldata _domains, bytes32[] calldata _routers) external; } diff --git a/src/interfaces/IValidatorAnnounce.sol b/src/interfaces/IValidatorAnnounce.sol index 938eb92..944dfd5 100755 --- a/src/interfaces/IValidatorAnnounce.sol +++ b/src/interfaces/IValidatorAnnounce.sol @@ -10,9 +10,7 @@ interface IValidatorAnnounce { * @param _validators The list of validators to get storage locations for * @return A list of announced storage locations */ - function getAnnouncedStorageLocations( - address[] calldata _validators - ) external view returns (string[][] memory); + function getAnnouncedStorageLocations(address[] calldata _validators) external view returns (string[][] memory); /** * @notice Announces a validator signature storage location @@ -21,9 +19,7 @@ interface IValidatorAnnounce { * @param _signature The signed validator announcement * @return True upon success */ - function announce( - address _validator, - string calldata _storageLocation, - bytes calldata _signature - ) external returns (bool); + function announce(address _validator, string calldata _storageLocation, bytes calldata _signature) + external + returns (bool); } diff --git a/src/interfaces/hooks/IMessageDispatcher.sol b/src/interfaces/hooks/IMessageDispatcher.sol index b905868..8830c73 100755 --- a/src/interfaces/hooks/IMessageDispatcher.sol +++ b/src/interfaces/hooks/IMessageDispatcher.sol @@ -15,16 +15,8 @@ interface IMessageDispatcher { * @param data Data that was dispatched */ event MessageDispatched( - bytes32 indexed messageId, - address indexed from, - uint256 indexed toChainId, - address to, - bytes data + bytes32 indexed messageId, address indexed from, uint256 indexed toChainId, address to, bytes data ); - function dispatchMessage( - uint256 toChainId, - address to, - bytes calldata data - ) external returns (bytes32); + function dispatchMessage(uint256 toChainId, address to, bytes calldata data) external returns (bytes32); } diff --git a/src/interfaces/hooks/IPostDispatchHook.sol b/src/interfaces/hooks/IPostDispatchHook.sol index 65b94f4..87d7901 100755 --- a/src/interfaces/hooks/IPostDispatchHook.sol +++ b/src/interfaces/hooks/IPostDispatchHook.sol @@ -27,19 +27,14 @@ interface IPostDispatchHook { * @param metadata metadata * @return Whether the hook supports metadata */ - function supportsMetadata( - bytes calldata metadata - ) external view returns (bool); + function supportsMetadata(bytes calldata metadata) external view returns (bool); /** * @notice Post action after a message is dispatched via the Mailbox * @param metadata The metadata required for the hook * @param message The message passed from the Mailbox.dispatch() call */ - function postDispatch( - bytes calldata metadata, - bytes calldata message - ) external payable; + function postDispatch(bytes calldata metadata, bytes calldata message) external payable; /** * @notice Compute the payment required by the postDispatch call @@ -47,8 +42,5 @@ interface IPostDispatchHook { * @param message The message passed from the Mailbox.dispatch() call * @return Quoted payment for the postDispatch call */ - function quoteDispatch( - bytes calldata metadata, - bytes calldata message - ) external view returns (uint256); + function quoteDispatch(bytes calldata metadata, bytes calldata message) external view returns (uint256); } diff --git a/src/interfaces/isms/IAggregationIsm.sol b/src/interfaces/isms/IAggregationIsm.sol index 69e2ddd..2657bec 100755 --- a/src/interfaces/isms/IAggregationIsm.sol +++ b/src/interfaces/isms/IAggregationIsm.sol @@ -12,7 +12,8 @@ interface IAggregationIsm is IInterchainSecurityModule { * @return modules The array of ISM addresses * @return threshold The number of modules needed to verify */ - function modulesAndThreshold( - bytes calldata _message - ) external view returns (address[] memory modules, uint8 threshold); + function modulesAndThreshold(bytes calldata _message) + external + view + returns (address[] memory modules, uint8 threshold); } diff --git a/src/interfaces/isms/ICcipReadIsm.sol b/src/interfaces/isms/ICcipReadIsm.sol index d0534b0..d871fa9 100755 --- a/src/interfaces/isms/ICcipReadIsm.sol +++ b/src/interfaces/isms/ICcipReadIsm.sol @@ -10,13 +10,7 @@ interface ICcipReadIsm is IInterchainSecurityModule { /// @param callData context needed for offchain service to service request /// @param callbackFunction function selector to call with offchain information /// @param extraData additional passthrough information to call callbackFunction with - error OffchainLookup( - address sender, - string[] urls, - bytes callData, - bytes4 callbackFunction, - bytes extraData - ); + error OffchainLookup(address sender, string[] urls, bytes callData, bytes4 callbackFunction, bytes extraData); /** * @notice Reverts with the data needed to query information offchain diff --git a/src/interfaces/isms/IMultisigIsm.sol b/src/interfaces/isms/IMultisigIsm.sol index 89c89e5..9fc42e5 100755 --- a/src/interfaces/isms/IMultisigIsm.sol +++ b/src/interfaces/isms/IMultisigIsm.sol @@ -13,7 +13,8 @@ interface IMultisigIsm is IInterchainSecurityModule { * @return validators The array of validator addresses * @return threshold The number of validator signatures needed */ - function validatorsAndThreshold( - bytes calldata _message - ) external view returns (address[] memory validators, uint8 threshold); + function validatorsAndThreshold(bytes calldata _message) + external + view + returns (address[] memory validators, uint8 threshold); } diff --git a/src/interfaces/isms/IRoutingIsm.sol b/src/interfaces/isms/IRoutingIsm.sol index 1218bc3..ba32b21 100755 --- a/src/interfaces/isms/IRoutingIsm.sol +++ b/src/interfaces/isms/IRoutingIsm.sol @@ -10,7 +10,5 @@ interface IRoutingIsm is IInterchainSecurityModule { * @param _message Formatted Manifold Finance AVS message (see Message.sol). * @return module The ISM to use to verify _message */ - function route( - bytes calldata _message - ) external view returns (IInterchainSecurityModule); + function route(bytes calldata _message) external view returns (IInterchainSecurityModule); } diff --git a/src/interfaces/isms/IWeightedMultisigIsm.sol b/src/interfaces/isms/IWeightedMultisigIsm.sol index 1a19195..b13b84e 100755 --- a/src/interfaces/isms/IWeightedMultisigIsm.sol +++ b/src/interfaces/isms/IWeightedMultisigIsm.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.6.11; - import {IInterchainSecurityModule} from "../IInterchainSecurityModule.sol"; interface IStaticWeightedMultisigIsm is IInterchainSecurityModule { @@ -19,9 +18,7 @@ interface IStaticWeightedMultisigIsm is IInterchainSecurityModule { * @return validators The validators and their weights * @return thresholdWeight The threshold weight required to pass verification */ - function validatorsAndThresholdWeight( - bytes calldata _message - ) + function validatorsAndThresholdWeight(bytes calldata _message) external view returns (ValidatorInfo[] memory validators, uint96 thresholdWeight); diff --git a/src/interfaces/optimism/ICrossDomainMessenger.sol b/src/interfaces/optimism/ICrossDomainMessenger.sol index 9bffafc..0a2849f 100755 --- a/src/interfaces/optimism/ICrossDomainMessenger.sol +++ b/src/interfaces/optimism/ICrossDomainMessenger.sol @@ -12,11 +12,7 @@ interface ICrossDomainMessenger { * @param _message Message to send to the target. * @param _gasLimit Gas limit for the provided message. */ - function sendMessage( - address _target, - bytes calldata _message, - uint32 _gasLimit - ) external payable; + function sendMessage(address _target, bytes calldata _message, uint32 _gasLimit) external payable; function relayMessage( uint256 _nonce, diff --git a/src/tokens/Native.sol b/src/tokens/Native.sol index 7637c0f..8269e7c 100755 --- a/src/tokens/Native.sol +++ b/src/tokens/Native.sol @@ -23,14 +23,10 @@ contract ManifoldNative is TokenRouter { /** * @notice Initializes the Token router * @param _hook The post-dispatch hook contract. - @param _interchainSecurityModule The interchain security module contract. - @param _owner The this contract. + * @param _interchainSecurityModule The interchain security module contract. + * @param _owner The this contract. */ - function initialize( - address _hook, - address _interchainSecurityModule, - address _owner - ) public initializer { + function initialize(address _hook, address _interchainSecurityModule, address _owner) public initializer { _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); } @@ -38,19 +34,19 @@ contract ManifoldNative is TokenRouter { * @inheritdoc TokenRouter * @dev uses (`msg.value` - `_amount`) as hook payment and `msg.sender` as refund address. */ - function transferRemote( - uint32 _destination, - bytes32 _recipient, - uint256 _amount - ) external payable virtual override returns (bytes32 messageId) { + function transferRemote(uint32 _destination, bytes32 _recipient, uint256 _amount) + external + payable + virtual + override + returns (bytes32 messageId) + { require(msg.value >= _amount, "Native: amount exceeds msg.value"); uint256 _hookPayment = msg.value - _amount; return _transferRemote(_destination, _recipient, _amount, _hookPayment); } - function balanceOf( - address _account - ) external view override returns (uint256) { + function balanceOf(address _account) external view override returns (uint256) { return _account.balance; } @@ -59,9 +55,7 @@ contract ManifoldNative is TokenRouter { * @dev No-op because native amount is transferred in `msg.value` * @dev Compiler will not include this in the bytecode. */ - function _transferFromSender( - uint256 - ) internal pure override returns (bytes memory) { + function _transferFromSender(uint256) internal pure override returns (bytes memory) { return bytes(""); // no metadata } diff --git a/src/tokens/extensions/ManifoldERC20.sol b/src/tokens/extensions/ManifoldERC20.sol index 098a52a..6f25678 100755 --- a/src/tokens/extensions/ManifoldERC20.sol +++ b/src/tokens/extensions/ManifoldERC20.sol @@ -13,20 +13,17 @@ import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ * @dev Supply on each chain is not constant but the aggregate supply across all chains is. */ contract FastManifoldERC20 is FastTokenRouter, ManifoldERC20 { - constructor( - uint8 __decimals, - address _mailbox - ) ManifoldERC20(__decimals, _mailbox) {} + constructor(uint8 __decimals, address _mailbox) ManifoldERC20(__decimals, _mailbox) {} /** * @dev delegates transfer logic to `_transferTo`. * @inheritdoc TokenRouter */ - function _handle( - uint32 _origin, - bytes32 _sender, - bytes calldata _message - ) internal virtual override(FastTokenRouter, TokenRouter) { + function _handle(uint32 _origin, bytes32 _sender, bytes calldata _message) + internal + virtual + override(FastTokenRouter, TokenRouter) + { FastTokenRouter._handle(_origin, _sender, _message); } @@ -34,10 +31,7 @@ contract FastManifoldERC20 is FastTokenRouter, ManifoldERC20 { * @dev Mints `_amount` of tokens to `_recipient`. * @inheritdoc FastTokenRouter */ - function _fastTransferTo( - address _recipient, - uint256 _amount - ) internal override { + function _fastTransferTo(address _recipient, uint256 _amount) internal override { _mint(_recipient, _amount); } @@ -45,16 +39,11 @@ contract FastManifoldERC20 is FastTokenRouter, ManifoldERC20 { * @dev Burns `_amount` of tokens from `_recipient`. * @inheritdoc FastTokenRouter */ - function _fastRecieveFrom( - address _sender, - uint256 _amount - ) internal override { + function _fastRecieveFrom(address _sender, uint256 _amount) internal override { _burn(_sender, _amount); } - function balanceOf( - address _account - ) public view virtual override(ManifoldERC20, TokenRouter) returns (uint256) { + function balanceOf(address _account) public view virtual override(ManifoldERC20, TokenRouter) returns (uint256) { return ERC20Upgradeable.balanceOf(_account); } } diff --git a/src/tokens/extensions/ManifoldERC20Collateral.sol b/src/tokens/extensions/ManifoldERC20Collateral.sol index b134ccb..9661ea6 100755 --- a/src/tokens/extensions/ManifoldERC20Collateral.sol +++ b/src/tokens/extensions/ManifoldERC20Collateral.sol @@ -19,20 +19,17 @@ contract FastManifoldERC20Collateral is FastTokenRouter, ManifoldERC20Collateral * @notice Constructor * @param erc20 Address of the token to keep as collateral */ - constructor( - address erc20, - address _mailbox - ) ManifoldERC20Collateral(erc20, _mailbox) {} + constructor(address erc20, address _mailbox) ManifoldERC20Collateral(erc20, _mailbox) {} /** * @dev delegates transfer logic to `_transferTo`. * @inheritdoc FastTokenRouter */ - function _handle( - uint32 _origin, - bytes32 _sender, - bytes calldata _message - ) internal virtual override(FastTokenRouter, TokenRouter) { + function _handle(uint32 _origin, bytes32 _sender, bytes calldata _message) + internal + virtual + override(FastTokenRouter, TokenRouter) + { FastTokenRouter._handle(_origin, _sender, _message); } @@ -40,10 +37,7 @@ contract FastManifoldERC20Collateral is FastTokenRouter, ManifoldERC20Collateral * @dev Transfers `_amount` of `wrappedToken` to `_recipient`. * @inheritdoc FastTokenRouter */ - function _fastTransferTo( - address _recipient, - uint256 _amount - ) internal override { + function _fastTransferTo(address _recipient, uint256 _amount) internal override { wrappedToken.safeTransfer(_recipient, _amount); } @@ -51,10 +45,7 @@ contract FastManifoldERC20Collateral is FastTokenRouter, ManifoldERC20Collateral * @dev Transfers in `_amount` of `wrappedToken` from `_recipient`. * @inheritdoc FastTokenRouter */ - function _fastRecieveFrom( - address _sender, - uint256 _amount - ) internal override { + function _fastRecieveFrom(address _sender, uint256 _amount) internal override { wrappedToken.safeTransferFrom(_sender, address(this), _amount); } } diff --git a/src/tokens/extensions/ManifoldERC4626.sol b/src/tokens/extensions/ManifoldERC4626.sol index 7c69196..47be562 100755 --- a/src/tokens/extensions/ManifoldERC4626.sol +++ b/src/tokens/extensions/ManifoldERC4626.sol @@ -21,11 +21,7 @@ contract ManifoldERC4626 is ManifoldERC20 { uint32 public immutable collateralDomain; uint256 public exchangeRate; // 1e10 - constructor( - uint8 _decimals, - address _mailbox, - uint32 _collateralDomain - ) ManifoldERC20(_decimals, _mailbox) { + constructor(uint8 _decimals, address _mailbox, uint32 _collateralDomain) ManifoldERC20(_decimals, _mailbox) { collateralDomain = _collateralDomain; exchangeRate = 1e10; _disableInitializers(); @@ -43,28 +39,14 @@ contract ManifoldERC4626 is ManifoldERC20 { ) internal virtual override returns (bytes32 messageId) { uint256 _shares = assetsToShares(_amountOrId); _transferFromSender(_shares); - bytes memory _tokenMessage = TokenMessage.format( - _recipient, - _shares, - bytes("") - ); + bytes memory _tokenMessage = TokenMessage.format(_recipient, _shares, bytes("")); - messageId = _Router_dispatch( - _destination, - _value, - _tokenMessage, - _hookMetadata, - _hook - ); + messageId = _Router_dispatch(_destination, _value, _tokenMessage, _hookMetadata, _hook); emit SentTransferRemote(_destination, _recipient, _amountOrId); } - function _handle( - uint32 _origin, - bytes32 _sender, - bytes calldata _message - ) internal virtual override { + function _handle(uint32 _origin, bytes32 _sender, bytes calldata _message) internal virtual override { if (_origin == collateralDomain) { exchangeRate = abi.decode(_message.metadata(), (uint256)); } @@ -72,10 +54,7 @@ contract ManifoldERC4626 is ManifoldERC20 { } // Override to send shares locally instead of assets - function transfer( - address to, - uint256 amount - ) public virtual override returns (bool) { + function transfer(address to, uint256 amount) public virtual override returns (bool) { address owner = _msgSender(); _transfer(owner, to, assetsToShares(amount)); return true; @@ -85,9 +64,7 @@ contract ManifoldERC4626 is ManifoldERC20 { return super.balanceOf(account); } - function balanceOf( - address account - ) public view virtual override returns (uint256) { + function balanceOf(address account) public view virtual override returns (uint256) { uint256 _balance = super.balanceOf(account); return sharesToAssets(_balance); } diff --git a/src/tokens/extensions/ManifoldERC4626Collateral.sol b/src/tokens/extensions/ManifoldERC4626Collateral.sol index a5b5b79..6965c34 100755 --- a/src/tokens/extensions/ManifoldERC4626Collateral.sol +++ b/src/tokens/extensions/ManifoldERC4626Collateral.sol @@ -18,21 +18,13 @@ contract ManifoldERC4626Collateral is ManifoldERC20Collateral { // Address of the ERC4626 compatible vault ERC4626 public immutable vault; uint256 public constant PRECISION = 1e10; - bytes32 public constant NULL_RECIPIENT = - 0x0000000000000000000000000000000000000000000000000000000000000001; + bytes32 public constant NULL_RECIPIENT = 0x0000000000000000000000000000000000000000000000000000000000000001; - constructor( - ERC4626 _vault, - address _mailbox - ) ManifoldERC20Collateral(_vault.asset(), _mailbox) { + constructor(ERC4626 _vault, address _mailbox) ManifoldERC20Collateral(_vault.asset(), _mailbox) { vault = _vault; } - function initialize( - address _hook, - address _interchainSecurityModule, - address _owner - ) public override initializer { + function initialize(address _hook, address _interchainSecurityModule, address _owner) public override initializer { _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); } @@ -47,26 +39,12 @@ contract ManifoldERC4626Collateral is ManifoldERC20Collateral { // Can't override _transferFromSender only because we need to pass shares in the token message _transferFromSender(_amount); uint256 _shares = _depositIntoVault(_amount); - uint256 _exchangeRate = PRECISION.mulDiv( - vault.totalAssets(), - vault.totalSupply(), - Math.Rounding.Down - ); + uint256 _exchangeRate = PRECISION.mulDiv(vault.totalAssets(), vault.totalSupply(), Math.Rounding.Down); bytes memory _tokenMetadata = abi.encode(_exchangeRate); - bytes memory _tokenMessage = TokenMessage.format( - _recipient, - _shares, - _tokenMetadata - ); + bytes memory _tokenMessage = TokenMessage.format(_recipient, _shares, _tokenMetadata); - messageId = _Router_dispatch( - _destination, - _value, - _tokenMessage, - _hookMetadata, - _hook - ); + messageId = _Router_dispatch(_destination, _value, _tokenMessage, _hookMetadata, _hook); emit SentTransferRemote(_destination, _recipient, _shares); } @@ -84,11 +62,7 @@ contract ManifoldERC4626Collateral is ManifoldERC20Collateral { * @dev Transfers `_amount` of `wrappedToken` from this contract to `_recipient`, and withdraws from vault * @inheritdoc ManifoldERC20Collateral */ - function _transferTo( - address _recipient, - uint256 _amount, - bytes calldata - ) internal virtual override { + function _transferTo(address _recipient, uint256 _amount, bytes calldata) internal virtual override { // withdraw with the specified amount of shares vault.redeem(_amount, _recipient, address(this)); } @@ -99,13 +73,6 @@ contract ManifoldERC4626Collateral is ManifoldERC20Collateral { */ function rebase(uint32 _destinationDomain) public payable { // force a rebase with an empty transfer to 0x1 - _transferRemote( - _destinationDomain, - NULL_RECIPIENT, - 0, - msg.value, - bytes(""), - address(0) - ); + _transferRemote(_destinationDomain, NULL_RECIPIENT, 0, msg.value, bytes(""), address(0)); } } diff --git a/src/tokens/extensions/ManifoldERC4626OwnerCollateral.sol b/src/tokens/extensions/ManifoldERC4626OwnerCollateral.sol index 93ce6b9..f98e4ec 100755 --- a/src/tokens/extensions/ManifoldERC4626OwnerCollateral.sol +++ b/src/tokens/extensions/ManifoldERC4626OwnerCollateral.sol @@ -17,18 +17,11 @@ contract ManifoldERC4626OwnerCollateral is ManifoldERC20Collateral { event ExcessSharesSwept(uint256 amount, uint256 assetsRedeemed); - constructor( - ERC4626 _vault, - address _mailbox - ) ManifoldERC20Collateral(_vault.asset(), _mailbox) { + constructor(ERC4626 _vault, address _mailbox) ManifoldERC20Collateral(_vault.asset(), _mailbox) { vault = _vault; } - function initialize( - address _hook, - address _interchainSecurityModule, - address _owner - ) public override initializer { + function initialize(address _hook, address _interchainSecurityModule, address _owner) public override initializer { wrappedToken.approve(address(vault), type(uint256).max); _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); } @@ -37,9 +30,7 @@ contract ManifoldERC4626OwnerCollateral is ManifoldERC20Collateral { * @dev Transfers `_amount` of `wrappedToken` from `msg.sender` to this contract, and deposit into vault * @inheritdoc ManifoldERC20Collateral */ - function _transferFromSender( - uint256 _amount - ) internal override returns (bytes memory metadata) { + function _transferFromSender(uint256 _amount) internal override returns (bytes memory metadata) { metadata = super._transferFromSender(_amount); _depositIntoVault(_amount); } @@ -57,11 +48,7 @@ contract ManifoldERC4626OwnerCollateral is ManifoldERC20Collateral { * @dev Transfers `_amount` of `wrappedToken` from this contract to `_recipient`, and withdraws from vault * @inheritdoc ManifoldERC20Collateral */ - function _transferTo( - address _recipient, - uint256 _amount, - bytes calldata - ) internal virtual override { + function _transferTo(address _recipient, uint256 _amount, bytes calldata) internal virtual override { _withdrawFromVault(_amount, _recipient); } @@ -79,13 +66,8 @@ contract ManifoldERC4626OwnerCollateral is ManifoldERC20Collateral { * @notice Allows the owner to redeem excess shares */ function sweep() external onlyOwner { - uint256 excessShares = vault.maxRedeem(address(this)) - - vault.convertToShares(assetDeposited); - uint256 assetsRedeemed = vault.redeem( - excessShares, - owner(), - address(this) - ); + uint256 excessShares = vault.maxRedeem(address(this)) - vault.convertToShares(assetDeposited); + uint256 assetsRedeemed = vault.redeem(excessShares, owner(), address(this)); emit ExcessSharesSwept(excessShares, assetsRedeemed); } } diff --git a/src/tokens/extensions/ManifoldERC721URICollateral.sol b/src/tokens/extensions/ManifoldERC721URICollateral.sol index ca05d4a..20ce817 100755 --- a/src/tokens/extensions/ManifoldERC721URICollateral.sol +++ b/src/tokens/extensions/ManifoldERC721URICollateral.sol @@ -3,7 +3,8 @@ pragma solidity >=0.8.0; import {ManifoldERC721Collateral} from "../ManifoldERC721Collateral.sol"; -import {IERC721MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; +import {IERC721MetadataUpgradeable} from + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/IERC721MetadataUpgradeable.sol"; /** * @title ERC721 Token Collateral that wraps an existing ERC721 with remote transfer and URI relay functionality. @@ -11,25 +12,15 @@ import {IERC721MetadataUpgradeable} from "@openzeppelin/contracts-upgradeable/to */ contract ManifoldERC721URICollateral is ManifoldERC721Collateral { // solhint-disable-next-line no-empty-blocks - constructor( - address erc721, - address _mailbox - ) ManifoldERC721Collateral(erc721, _mailbox) {} + constructor(address erc721, address _mailbox) ManifoldERC721Collateral(erc721, _mailbox) {} /** * @dev Transfers `_tokenId` of `wrappedToken` from `msg.sender` to this contract. * @return The URI of `_tokenId` on `wrappedToken`. * @inheritdoc ManifoldERC721Collateral */ - function _transferFromSender( - uint256 _tokenId - ) internal override returns (bytes memory) { + function _transferFromSender(uint256 _tokenId) internal override returns (bytes memory) { ManifoldERC721Collateral._transferFromSender(_tokenId); - return - bytes( - IERC721MetadataUpgradeable(address(wrappedToken)).tokenURI( - _tokenId - ) - ); + return bytes(IERC721MetadataUpgradeable(address(wrappedToken)).tokenURI(_tokenId)); } } diff --git a/src/tokens/extensions/ManifoldERC721URIStorage.sol b/src/tokens/extensions/ManifoldERC721URIStorage.sol index c5886b3..2f447d2 100755 --- a/src/tokens/extensions/ManifoldERC721URIStorage.sol +++ b/src/tokens/extensions/ManifoldERC721URIStorage.sol @@ -3,8 +3,10 @@ pragma solidity >=0.8.0; import {ManifoldERC721} from "../ManifoldERC721.sol"; -import {ERC721URIStorageUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; -import {ERC721EnumerableUpgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; +import {ERC721URIStorageUpgradeable} from + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721URIStorageUpgradeable.sol"; +import {ERC721EnumerableUpgradeable} from + "@openzeppelin/contracts-upgradeable/token/ERC721/extensions/ERC721EnumerableUpgradeable.sol"; import {ERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/ERC721Upgradeable.sol"; import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC721/IERC721Upgradeable.sol"; @@ -15,9 +17,7 @@ import {IERC721Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC7 contract ManifoldERC721URIStorage is ManifoldERC721, ERC721URIStorageUpgradeable { constructor(address _mailbox) ManifoldERC721(_mailbox) {} - function balanceOf( - address account - ) + function balanceOf(address account) public view override(ManifoldERC721, ERC721Upgradeable, IERC721Upgradeable) @@ -30,9 +30,7 @@ contract ManifoldERC721URIStorage is ManifoldERC721, ERC721URIStorageUpgradeable * @return _tokenURI The URI of `_tokenId`. * @inheritdoc ManifoldERC721 */ - function _transferFromSender( - uint256 _tokenId - ) internal override returns (bytes memory _tokenURI) { + function _transferFromSender(uint256 _tokenId) internal override returns (bytes memory _tokenURI) { _tokenURI = bytes(tokenURI(_tokenId)); // requires minted ManifoldERC721._transferFromSender(_tokenId); } @@ -41,18 +39,12 @@ contract ManifoldERC721URIStorage is ManifoldERC721, ERC721URIStorageUpgradeable * @dev Sets the URI for `_tokenId` to `_tokenURI`. * @inheritdoc ManifoldERC721 */ - function _transferTo( - address _recipient, - uint256 _tokenId, - bytes calldata _tokenURI - ) internal override { + function _transferTo(address _recipient, uint256 _tokenId, bytes calldata _tokenURI) internal override { ManifoldERC721._transferTo(_recipient, _tokenId, _tokenURI); _setTokenURI(_tokenId, string(_tokenURI)); // requires minted } - function tokenURI( - uint256 tokenId - ) + function tokenURI(uint256 tokenId) public view override(ERC721Upgradeable, ERC721URIStorageUpgradeable) @@ -61,23 +53,14 @@ contract ManifoldERC721URIStorage is ManifoldERC721, ERC721URIStorageUpgradeable return ERC721URIStorageUpgradeable.tokenURI(tokenId); } - function _beforeTokenTransfer( - address from, - address to, - uint256 tokenId, - uint256 batchSize - ) internal override(ERC721EnumerableUpgradeable, ERC721Upgradeable) { - ERC721EnumerableUpgradeable._beforeTokenTransfer( - from, - to, - tokenId, - batchSize - ); + function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) + internal + override(ERC721EnumerableUpgradeable, ERC721Upgradeable) + { + ERC721EnumerableUpgradeable._beforeTokenTransfer(from, to, tokenId, batchSize); } - function supportsInterface( - bytes4 interfaceId - ) + function supportsInterface(bytes4 interfaceId) public view override(ERC721EnumerableUpgradeable, ERC721URIStorageUpgradeable) @@ -86,9 +69,7 @@ contract ManifoldERC721URIStorage is ManifoldERC721, ERC721URIStorageUpgradeable return ERC721EnumerableUpgradeable.supportsInterface(interfaceId); } - function _burn( - uint256 tokenId - ) internal override(ERC721URIStorageUpgradeable, ERC721Upgradeable) { + function _burn(uint256 tokenId) internal override(ERC721URIStorageUpgradeable, ERC721Upgradeable) { ERC721URIStorageUpgradeable._burn(tokenId); } } diff --git a/src/tokens/extensions/ManifoldFiatToken.sol b/src/tokens/extensions/ManifoldFiatToken.sol index 3f6a0ee..2d48b0a 100755 --- a/src/tokens/extensions/ManifoldFiatToken.sol +++ b/src/tokens/extensions/ManifoldFiatToken.sol @@ -6,28 +6,16 @@ import {ManifoldERC20Collateral} from "../ManifoldERC20Collateral.sol"; // see https://github.com/circlefin/stablecoin-evm/blob/master/doc/tokendesign.md#issuing-and-destroying-tokens contract ManifoldFiatToken is ManifoldERC20Collateral { - constructor( - address _fiatToken, - address _mailbox - ) ManifoldERC20Collateral(_fiatToken, _mailbox) {} + constructor(address _fiatToken, address _mailbox) ManifoldERC20Collateral(_fiatToken, _mailbox) {} - function _transferFromSender( - uint256 _amount - ) internal override returns (bytes memory metadata) { + function _transferFromSender(uint256 _amount) internal override returns (bytes memory metadata) { // transfer amount to address(this) metadata = super._transferFromSender(_amount); // burn amount of address(this) balance IFiatToken(address(wrappedToken)).burn(_amount); } - function _transferTo( - address _recipient, - uint256 _amount, - bytes calldata /*metadata*/ - ) internal override { - require( - IFiatToken(address(wrappedToken)).mint(_recipient, _amount), - "FiatToken mint failed" - ); + function _transferTo(address _recipient, uint256 _amount, bytes calldata /*metadata*/ ) internal override { + require(IFiatToken(address(wrappedToken)).mint(_recipient, _amount), "FiatToken mint failed"); } } diff --git a/src/tokens/extensions/ManifoldNativeScaled.sol b/src/tokens/extensions/ManifoldNativeScaled.sol index 647d0b4..6f5cb8d 100755 --- a/src/tokens/extensions/ManifoldNativeScaled.sol +++ b/src/tokens/extensions/ManifoldNativeScaled.sol @@ -21,21 +21,16 @@ contract ManifoldNativeScaled is ManifoldNative { * @inheritdoc ManifoldNative * @dev Sends scaled `msg.value` (divided by `scale`) to `_recipient`. */ - function transferRemote( - uint32 _destination, - bytes32 _recipient, - uint256 _amount - ) external payable override returns (bytes32 messageId) { + function transferRemote(uint32 _destination, bytes32 _recipient, uint256 _amount) + external + payable + override + returns (bytes32 messageId) + { require(msg.value >= _amount, "Native: amount exceeds msg.value"); uint256 _hookPayment = msg.value - _amount; uint256 _scaledAmount = _amount / scale; - return - _transferRemote( - _destination, - _recipient, - _scaledAmount, - _hookPayment - ); + return _transferRemote(_destination, _recipient, _scaledAmount, _hookPayment); } /** diff --git a/src/tokens/extensions/ManifoldXERC20.sol b/src/tokens/extensions/ManifoldXERC20.sol index 4fff1be..f74175f 100755 --- a/src/tokens/extensions/ManifoldXERC20.sol +++ b/src/tokens/extensions/ManifoldXERC20.sol @@ -5,25 +5,16 @@ import {IXERC20} from "../interfaces/IXERC20.sol"; import {ManifoldERC20Collateral} from "../ManifoldERC20Collateral.sol"; contract ManifoldXERC20 is ManifoldERC20Collateral { - constructor( - address _xerc20, - address _mailbox - ) ManifoldERC20Collateral(_xerc20, _mailbox) { + constructor(address _xerc20, address _mailbox) ManifoldERC20Collateral(_xerc20, _mailbox) { _disableInitializers(); } - function _transferFromSender( - uint256 _amountOrId - ) internal override returns (bytes memory metadata) { + function _transferFromSender(uint256 _amountOrId) internal override returns (bytes memory metadata) { IXERC20(address(wrappedToken)).burn(msg.sender, _amountOrId); return ""; } - function _transferTo( - address _recipient, - uint256 _amountOrId, - bytes calldata /*metadata*/ - ) internal override { + function _transferTo(address _recipient, uint256 _amountOrId, bytes calldata /*metadata*/ ) internal override { IXERC20(address(wrappedToken)).mint(_recipient, _amountOrId); } } diff --git a/src/tokens/extensions/ManifoldXERC20Lockbox.sol b/src/tokens/extensions/ManifoldXERC20Lockbox.sol index 2dc7164..7bebf8b 100755 --- a/src/tokens/extensions/ManifoldXERC20Lockbox.sol +++ b/src/tokens/extensions/ManifoldXERC20Lockbox.sol @@ -11,10 +11,9 @@ contract ManifoldXERC20Lockbox is ManifoldERC20Collateral { IXERC20Lockbox public immutable lockbox; IXERC20 public immutable xERC20; - constructor( - address _lockbox, - address _mailbox - ) ManifoldERC20Collateral(address(IXERC20Lockbox(_lockbox).ERC20()), _mailbox) { + constructor(address _lockbox, address _mailbox) + ManifoldERC20Collateral(address(IXERC20Lockbox(_lockbox).ERC20()), _mailbox) + { lockbox = IXERC20Lockbox(_lockbox); xERC20 = lockbox.XERC20(); approveLockbox(); @@ -26,14 +25,8 @@ contract ManifoldXERC20Lockbox is ManifoldERC20Collateral { * @dev This function is idempotent and need not be access controlled */ function approveLockbox() public { - require( - IERC20(wrappedToken).approve(address(lockbox), MAX_INT), - "erc20 lockbox approve failed" - ); - require( - xERC20.approve(address(lockbox), MAX_INT), - "xerc20 lockbox approve failed" - ); + require(IERC20(wrappedToken).approve(address(lockbox), MAX_INT), "erc20 lockbox approve failed"); + require(xERC20.approve(address(lockbox), MAX_INT), "xerc20 lockbox approve failed"); } /** @@ -42,18 +35,12 @@ contract ManifoldXERC20Lockbox is ManifoldERC20Collateral { * @param _ism The address of the interchain security module * @param _owner The address of the owner */ - function initialize( - address _hook, - address _ism, - address _owner - ) public override initializer { + function initialize(address _hook, address _ism, address _owner) public override initializer { approveLockbox(); _MailboxClient_initialize(_hook, _ism, _owner); } - function _transferFromSender( - uint256 _amount - ) internal override returns (bytes memory) { + function _transferFromSender(uint256 _amount) internal override returns (bytes memory) { // transfer erc20 from sender super._transferFromSender(_amount); // convert erc20 to xERC20 @@ -63,11 +50,7 @@ contract ManifoldXERC20Lockbox is ManifoldERC20Collateral { return bytes(""); } - function _transferTo( - address _recipient, - uint256 _amount, - bytes calldata /*metadata*/ - ) internal override { + function _transferTo(address _recipient, uint256 _amount, bytes calldata /*metadata*/ ) internal override { // mint xERC20 xERC20.mint(address(this), _amount); // convert xERC20 to erc20 diff --git a/src/tokens/interfaces/IXERC20.sol b/src/tokens/interfaces/IXERC20.sol index b933af1..42d668f 100755 --- a/src/tokens/interfaces/IXERC20.sol +++ b/src/tokens/interfaces/IXERC20.sol @@ -29,11 +29,7 @@ interface IXERC20 is IERC20 { * @param _burningLimit The updated burning limit we are setting to the bridge * @param _bridge The address of the bridge we are setting the limits too */ - function setLimits( - address _bridge, - uint256 _mintingLimit, - uint256 _burningLimit - ) external; + function setLimits(address _bridge, uint256 _mintingLimit, uint256 _burningLimit) external; function owner() external returns (address); @@ -42,18 +38,14 @@ interface IXERC20 is IERC20 { * @param _bridge the bridge we are viewing the limits of * @return _limit The limit the bridge has */ - function burningCurrentLimitOf( - address _bridge - ) external view returns (uint256 _limit); + function burningCurrentLimitOf(address _bridge) external view returns (uint256 _limit); /** * @notice Returns the current limit of a bridge * @param _bridge the bridge we are viewing the limits of * @return _limit The limit the bridge has */ - function mintingCurrentLimitOf( - address _bridge - ) external view returns (uint256 _limit); + function mintingCurrentLimitOf(address _bridge) external view returns (uint256 _limit); /** * @notice Returns the max limit of a minter @@ -61,9 +53,7 @@ interface IXERC20 is IERC20 { * @param _minter The minter we are viewing the limits of * @return _limit The limit the minter has */ - function mintingMaxLimitOf( - address _minter - ) external view returns (uint256 _limit); + function mintingMaxLimitOf(address _minter) external view returns (uint256 _limit); /** * @notice Returns the max limit of a bridge @@ -71,8 +61,5 @@ interface IXERC20 is IERC20 { * @param _bridge the bridge we are viewing the limits of * @return _limit The limit the bridge has */ - - function burningMaxLimitOf( - address _bridge - ) external view returns (uint256 _limit); + function burningMaxLimitOf(address _bridge) external view returns (uint256 _limit); } diff --git a/src/tokens/interfaces/IXERC20Lockbox.sol b/src/tokens/interfaces/IXERC20Lockbox.sol index ba01f7b..5ebeee7 100755 --- a/src/tokens/interfaces/IXERC20Lockbox.sol +++ b/src/tokens/interfaces/IXERC20Lockbox.sol @@ -22,7 +22,6 @@ interface IXERC20Lockbox { * * @param _amount The amount of tokens to deposit */ - function deposit(uint256 _amount) external; /** @@ -31,7 +30,6 @@ interface IXERC20Lockbox { * @param _user The user to send the XERC20 to * @param _amount The amount of tokens to deposit */ - function depositTo(address _user, uint256 _amount) external; /** @@ -39,7 +37,6 @@ interface IXERC20Lockbox { * * @param _user The user to send the XERC20 to */ - function depositNativeTo(address _user) external payable; /** @@ -47,7 +44,6 @@ interface IXERC20Lockbox { * * @param _amount The amount of tokens to withdraw */ - function withdraw(uint256 _amount) external; /** @@ -56,6 +52,5 @@ interface IXERC20Lockbox { * @param _user The user to withdraw to * @param _amount The amount of tokens to withdraw */ - function withdrawTo(address _user, uint256 _amount) external; } diff --git a/src/tokens/libs/FastTokenRouter.sol b/src/tokens/libs/FastTokenRouter.sol index 8e4418a..e06666b 100755 --- a/src/tokens/libs/FastTokenRouter.sol +++ b/src/tokens/libs/FastTokenRouter.sol @@ -22,11 +22,7 @@ abstract contract FastTokenRouter is TokenRouter { * @dev delegates transfer logic to `_transferTo`. * @inheritdoc TokenRouter */ - function _handle( - uint32 _origin, - bytes32, - bytes calldata _message - ) internal virtual override { + function _handle(uint32 _origin, bytes32, bytes calldata _message) internal virtual override { bytes32 recipient = _message.recipient(); uint256 amount = _message.amount(); bytes calldata metadata = _message.metadata(); @@ -38,18 +34,11 @@ abstract contract FastTokenRouter is TokenRouter { * @dev Transfers `_amount` of token to `_recipient`/`fastFiller` who provided LP. * @dev Called by `handle` after message decoding. */ - function _transferTo( - address _recipient, - uint256 _amount, - uint32 _origin, - bytes calldata _metadata - ) internal virtual { - address _tokenRecipient = _getTokenRecipient( - _recipient, - _amount, - _origin, - _metadata - ); + function _transferTo(address _recipient, uint256 _amount, uint32 _origin, bytes calldata _metadata) + internal + virtual + { + address _tokenRecipient = _getTokenRecipient(_recipient, _amount, _origin, _metadata); _fastTransferTo(_tokenRecipient, _amount); } @@ -68,17 +57,8 @@ abstract contract FastTokenRouter is TokenRouter { uint32 _origin, uint256 _fastTransferId ) external virtual { - bytes32 filledFastTransfersKey = _getFastTransfersKey( - _origin, - _fastTransferId, - _amount, - _fastFee, - _recipient - ); - require( - filledFastTransfers[filledFastTransfersKey] == address(0), - "request already filled" - ); + bytes32 filledFastTransfersKey = _getFastTransfersKey(_origin, _fastTransferId, _amount, _fastFee, _recipient); + require(filledFastTransfers[filledFastTransfersKey] == address(0), "request already filled"); filledFastTransfers[filledFastTransfersKey] = msg.sender; @@ -95,25 +75,18 @@ abstract contract FastTokenRouter is TokenRouter { * @param _amountOrId The amount or identifier of tokens to be sent to the remote recipient. * @return messageId The identifier of the dispatched message. */ - function fastTransferRemote( - uint32 _destination, - bytes32 _recipient, - uint256 _amountOrId, - uint256 _fastFee - ) public payable virtual returns (bytes32 messageId) { + function fastTransferRemote(uint32 _destination, bytes32 _recipient, uint256 _amountOrId, uint256 _fastFee) + public + payable + virtual + returns (bytes32 messageId) + { uint256 _fastTransferId = fastTransferId + 1; fastTransferId = _fastTransferId; - bytes memory metadata = _fastTransferFromSender( - _amountOrId, - _fastFee, - _fastTransferId - ); + bytes memory metadata = _fastTransferFromSender(_amountOrId, _fastFee, _fastTransferId); messageId = _GasRouter_dispatch( - _destination, - msg.value, - TokenMessage.format(_recipient, _amountOrId, metadata), - address(hook) + _destination, msg.value, TokenMessage.format(_recipient, _amountOrId, metadata), address(hook) ); emit SentTransferRemote(_destination, _recipient, _amountOrId); } @@ -123,11 +96,11 @@ abstract contract FastTokenRouter is TokenRouter { * @dev Pays `_fastFee` of tokens to LP on source chain. * @dev Returns `fastFee` as bytes in the form of metadata. */ - function _fastTransferFromSender( - uint256 _amount, - uint256 _fastFee, - uint256 _fastTransferId - ) internal virtual returns (bytes memory) { + function _fastTransferFromSender(uint256 _amount, uint256 _fastFee, uint256 _fastTransferId) + internal + virtual + returns (bytes memory) + { _fastRecieveFrom(msg.sender, _amount); return abi.encode(_fastFee, _fastTransferId); } @@ -136,31 +109,20 @@ abstract contract FastTokenRouter is TokenRouter { * @dev returns an address that indicates who should receive the bridged tokens. * @dev if _fastFees was included and someone filled the order before the mailbox made the contract call, the filler gets the funds. */ - function _getTokenRecipient( - address _recipient, - uint256 _amount, - uint32 _origin, - bytes calldata _metadata - ) internal view returns (address) { + function _getTokenRecipient(address _recipient, uint256 _amount, uint32 _origin, bytes calldata _metadata) + internal + view + returns (address) + { if (_metadata.length == 0) { return _recipient; } // decode metadata to extract `_fastFee` and `_fastTransferId`. - (uint256 _fastFee, uint256 _fastTransferId) = abi.decode( - _metadata, - (uint256, uint256) - ); + (uint256 _fastFee, uint256 _fastTransferId) = abi.decode(_metadata, (uint256, uint256)); - address _fillerAddress = filledFastTransfers[ - _getFastTransfersKey( - _origin, - _fastTransferId, - _amount, - _fastFee, - _recipient - ) - ]; + address _fillerAddress = + filledFastTransfers[_getFastTransfersKey(_origin, _fastTransferId, _amount, _fastFee, _recipient)]; if (_fillerAddress != address(0)) { return _fillerAddress; } @@ -178,33 +140,18 @@ abstract contract FastTokenRouter is TokenRouter { uint256 _fastFee, address _recipient ) internal pure returns (bytes32) { - return - keccak256( - abi.encodePacked( - _origin, - _fastTransferId, - _amount, - _fastFee, - _recipient - ) - ); + return keccak256(abi.encodePacked(_origin, _fastTransferId, _amount, _fastFee, _recipient)); } /** * @dev Should transfer `_amount` of tokens to `_recipient`. * @dev The implementation is delegated. */ - function _fastTransferTo( - address _recipient, - uint256 _amount - ) internal virtual; + function _fastTransferTo(address _recipient, uint256 _amount) internal virtual; /** * @dev Should collect `amount` of tokens from `_sender`. * @dev The implementation is delegated. */ - function _fastRecieveFrom( - address _sender, - uint256 _amount - ) internal virtual; + function _fastRecieveFrom(address _sender, uint256 _amount) internal virtual; } diff --git a/src/tokens/libs/TokenMessage.sol b/src/tokens/libs/TokenMessage.sol index d593b1e..4067632 100755 --- a/src/tokens/libs/TokenMessage.sol +++ b/src/tokens/libs/TokenMessage.sol @@ -2,11 +2,7 @@ pragma solidity >=0.8.0; library TokenMessage { - function format( - bytes32 _recipient, - uint256 _amount, - bytes memory _metadata - ) internal pure returns (bytes memory) { + function format(bytes32 _recipient, uint256 _amount, bytes memory _metadata) internal pure returns (bytes memory) { return abi.encodePacked(_recipient, _amount, _metadata); } @@ -23,9 +19,7 @@ library TokenMessage { return amount(message); } - function metadata( - bytes calldata message - ) internal pure returns (bytes calldata) { + function metadata(bytes calldata message) internal pure returns (bytes calldata) { return message[64:]; } } From f014f4ca3e01583d72eb2a33bd6564026b5c6b9d Mon Sep 17 00:00:00 2001 From: sam bacha Date: Thu, 15 Aug 2024 22:37:42 -0700 Subject: [PATCH 5/8] chore(repo): changelog update --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7adc3a2..6cc383a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,14 @@ All notable changes to this project will be documented in this file. Dates are d Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog). +#### [v0.4.1](https://github.com/sambacha/eigenlayer-template/compare/v0.4.0...v0.4.1) + +> 15 August 2024 + +- feat(tokens): init support [`842722d`](https://github.com/sambacha/eigenlayer-template/commit/842722d87b48639df8e631e8c8d158ca4906bb08) +- fix(fmt): lint apply [`48d367d`](https://github.com/sambacha/eigenlayer-template/commit/48d367d5fda081aa5882529fcb347eaf2faf6063) +- feat(lido): init support rebasing [`cfd5013`](https://github.com/sambacha/eigenlayer-template/commit/cfd5013c4dd20e43b7703dcb7431f1dc7f1d1acb) + #### v0.4.0 > 15 August 2024 From bec50d4fbf9c4af04ca3c426cea225c4ecc3cd18 Mon Sep 17 00:00:00 2001 From: sam bacha Date: Thu, 15 Aug 2024 22:45:21 -0700 Subject: [PATCH 6/8] refactor(avs): interfaces cleanup --- foundry.toml | 2 +- src/interfaces/avs/IRemoteChallenger.sol | 13 ++ .../avs/{ => vendored}/IAVSDirectory.sol | 2 +- .../avs/vendored/IDelegationManager.sol | 37 ++++++ .../IECDSAStakeRegistryEventsAndErrors.sol | 112 ++++++++++++++++++ .../avs/vendored/IPaymentCoordinator.sol | 46 +++++++ .../avs/vendored/IServiceManager.sol | 28 +++++ .../avs/vendored/IServiceManagerUI.sol | 67 +++++++++++ .../avs/vendored/ISignatureUtils.sol | 27 +++++ src/interfaces/avs/vendored/ISlasher.sol | 11 ++ src/interfaces/avs/vendored/IStrategy.sol | 107 +++++++++++++++++ src/tokens/Native.sol | 77 ------------ src/tokens/extensions/ManifoldERC20.sol | 49 -------- 13 files changed, 450 insertions(+), 128 deletions(-) create mode 100644 src/interfaces/avs/IRemoteChallenger.sol rename src/interfaces/avs/{ => vendored}/IAVSDirectory.sol (94%) mode change 100644 => 100755 create mode 100755 src/interfaces/avs/vendored/IDelegationManager.sol create mode 100755 src/interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol create mode 100755 src/interfaces/avs/vendored/IPaymentCoordinator.sol create mode 100755 src/interfaces/avs/vendored/IServiceManager.sol create mode 100755 src/interfaces/avs/vendored/IServiceManagerUI.sol create mode 100755 src/interfaces/avs/vendored/ISignatureUtils.sol create mode 100755 src/interfaces/avs/vendored/ISlasher.sol create mode 100755 src/interfaces/avs/vendored/IStrategy.sol delete mode 100755 src/tokens/Native.sol delete mode 100755 src/tokens/extensions/ManifoldERC20.sol diff --git a/foundry.toml b/foundry.toml index 2cb6049..5d0bde6 100644 --- a/foundry.toml +++ b/foundry.toml @@ -5,7 +5,7 @@ script = "script" out = "out" libs = ["lib"] remappings = [ - "@openzeppelin-upgrades/=lib/eigenlayer-middleware/lib/openzeppelin-contracts-upgradeable/", + "@openzeppelin-upgrades/=/lib/openzeppelin-contracts-upgradeable/contracts/", "@openzeppelin=/lib/openzeppelin-contracts/contracts/", "ds-test/=lib/eigenlayer-middleware/lib/ds-test/src/", "eigenlayer-contracts/=lib/eigenlayer-middleware/lib/eigenlayer-contracts/", diff --git a/src/interfaces/avs/IRemoteChallenger.sol b/src/interfaces/avs/IRemoteChallenger.sol new file mode 100644 index 0000000..4270031 --- /dev/null +++ b/src/interfaces/avs/IRemoteChallenger.sol @@ -0,0 +1,13 @@ +// SPDX-License-Identifier: MIT OR Apache-2.0 +pragma solidity >=0.8.0; + + +interface IRemoteChallenger { + /// @notice Returns the number of blocks that must be mined before a challenge can be handled + /// @return The number of blocks that must be mined before a challenge can be handled + function challengeDelayBlocks() external view returns (uint256); + + /// @notice Handles a challenge for an operator + /// @param operator The address of the operator + function handleChallenge(address operator) external; +} \ No newline at end of file diff --git a/src/interfaces/avs/IAVSDirectory.sol b/src/interfaces/avs/vendored/IAVSDirectory.sol old mode 100644 new mode 100755 similarity index 94% rename from src/interfaces/avs/IAVSDirectory.sol rename to src/interfaces/avs/vendored/IAVSDirectory.sol index b880fb2..d8003a6 --- a/src/interfaces/avs/IAVSDirectory.sol +++ b/src/interfaces/avs/vendored/IAVSDirectory.sol @@ -3,7 +3,7 @@ pragma solidity >=0.8.0; import "./ISignatureUtils.sol"; -/// part of mock interfaces for vendoring necessary Eigenlayer contracts for the Manifold Finance AVS +/// part of mock interfaces for vendoring necessary Eigenlayer contracts for the hyperlane AVS /// @author Layr Labs, Inc. interface IAVSDirectory is ISignatureUtils { enum OperatorAVSRegistrationStatus { diff --git a/src/interfaces/avs/vendored/IDelegationManager.sol b/src/interfaces/avs/vendored/IDelegationManager.sol new file mode 100755 index 0000000..50fe929 --- /dev/null +++ b/src/interfaces/avs/vendored/IDelegationManager.sol @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity >=0.8.0; + +import {IStrategy} from "./IStrategy.sol"; + +/** + * @title DelegationManager + * @author Layr Labs, Inc. + * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service + * @notice This is the contract for delegation in EigenLayer. The main functionalities of this contract are + * - enabling anyone to register as an operator in EigenLayer + * - allowing operators to specify parameters related to stakers who delegate to them + * - enabling any staker to delegate its stake to the operator of its choice (a given staker can only delegate to a single operator at a time) + * - enabling a staker to undelegate its assets from the operator it is delegated to (performed as part of the withdrawal process, initiated through the StrategyManager) + */ +interface IDelegationManager { + struct OperatorDetails { + address earningsReceiver; + address delegationApprover; + uint32 stakerOptOutWindowBlocks; + } + + event OperatorMetadataURIUpdated( + address indexed operator, + string metadataURI + ); + + function registerAsOperator( + OperatorDetails calldata registeringOperatorDetails, + string calldata metadataURI + ) external; + + function getOperatorShares( + address operator, + IStrategy[] memory strategies + ) external view returns (uint256[] memory); +} diff --git a/src/interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol b/src/interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol new file mode 100755 index 0000000..07f6323 --- /dev/null +++ b/src/interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol @@ -0,0 +1,112 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.12; + +import {IStrategy} from "./IStrategy.sol"; + +struct StrategyParams { + IStrategy strategy; // The strategy contract reference + uint96 multiplier; // The multiplier applied to the strategy +} + +struct Quorum { + StrategyParams[] strategies; // An array of strategy parameters to define the quorum +} + +interface IECDSAStakeRegistryEventsAndErrors { + /// @notice Emitted when the system registers an operator + /// @param _operator The address of the registered operator + /// @param _avs The address of the associated AVS + event OperatorRegistered(address indexed _operator, address indexed _avs); + + /// @notice Emitted when the system deregisters an operator + /// @param _operator The address of the deregistered operator + /// @param _avs The address of the associated AVS + event OperatorDeregistered(address indexed _operator, address indexed _avs); + + /// @notice Emitted when the system updates the quorum + /// @param _old The previous quorum configuration + /// @param _new The new quorum configuration + event QuorumUpdated(Quorum _old, Quorum _new); + + /// @notice Emitted when the weight to join the operator set updates + /// @param _old The previous minimum weight + /// @param _new The new minimumWeight + event MinimumWeightUpdated(uint256 _old, uint256 _new); + + /// @notice Emitted when the weight required to be an operator changes + /// @param oldMinimumWeight The previous weight + /// @param newMinimumWeight The updated weight + event UpdateMinimumWeight( + uint256 oldMinimumWeight, + uint256 newMinimumWeight + ); + + /// @notice Emitted when the system updates an operator's weight + /// @param _operator The address of the operator updated + /// @param oldWeight The operator's weight before the update + /// @param newWeight The operator's weight after the update + event OperatorWeightUpdated( + address indexed _operator, + uint256 oldWeight, + uint256 newWeight + ); + + /// @notice Emitted when the system updates the total weight + /// @param oldTotalWeight The total weight before the update + /// @param newTotalWeight The total weight after the update + event TotalWeightUpdated(uint256 oldTotalWeight, uint256 newTotalWeight); + + /// @notice Emits when setting a new threshold weight. + event ThresholdWeightUpdated(uint256 _thresholdWeight); + + /// @notice Emitted when an operator's signing key is updated + /// @param operator The address of the operator whose signing key was updated + /// @param updateBlock The block number at which the signing key was updated + /// @param newSigningKey The operator's signing key after the update + /// @param oldSigningKey The operator's signing key before the update + event SigningKeyUpdate( + address indexed operator, + uint256 indexed updateBlock, + address indexed newSigningKey, + address oldSigningKey + ); + /// @notice Indicates when the lengths of the signers array and signatures array do not match. + + error LengthMismatch(); + + /// @notice Indicates encountering an invalid length for the signers or signatures array. + error InvalidLength(); + + /// @notice Indicates encountering an invalid signature. + error InvalidSignature(); + + /// @notice Thrown when the threshold update is greater than BPS + error InvalidThreshold(); + + /// @notice Thrown when missing operators in an update + error MustUpdateAllOperators(); + + /// @notice Reference blocks must be for blocks that have already been confirmed + error InvalidReferenceBlock(); + + /// @notice Indicates operator weights were out of sync and the signed weight exceed the total + error InvalidSignedWeight(); + + /// @notice Indicates the total signed stake fails to meet the required threshold. + error InsufficientSignedStake(); + + /// @notice Indicates an individual signer's weight fails to meet the required threshold. + error InsufficientWeight(); + + /// @notice Indicates the quorum is invalid + error InvalidQuorum(); + + /// @notice Indicates the system finds a list of items unsorted + error NotSorted(); + + /// @notice Thrown when registering an already registered operator + error OperatorAlreadyRegistered(); + + /// @notice Thrown when de-registering or updating the stake for an unregistered operator + error OperatorNotRegistered(); +} diff --git a/src/interfaces/avs/vendored/IPaymentCoordinator.sol b/src/interfaces/avs/vendored/IPaymentCoordinator.sol new file mode 100755 index 0000000..818b84d --- /dev/null +++ b/src/interfaces/avs/vendored/IPaymentCoordinator.sol @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity >=0.8.0; + +import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; +import "./IStrategy.sol"; + +/** + * @title Interface for the `IPaymentCoordinator` contract. + * @author Layr Labs, Inc. + * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service + * @notice Allows AVSs to make "Range Payments", which get distributed amongst the AVSs' confirmed + * Operators and the Stakers delegated to those Operators. + * Calculations are performed based on the completed Range Payments, with the results posted in + * a Merkle root against which Stakers & Operators can make claims. + */ +interface IPaymentCoordinator { + /// STRUCTS /// + struct StrategyAndMultiplier { + IStrategy strategy; + // weight used to compare shares in multiple strategies against one another + uint96 multiplier; + } + + struct RangePayment { + // Strategies & relative weights of shares in the strategies + StrategyAndMultiplier[] strategiesAndMultipliers; + IERC20 token; + uint256 amount; + uint64 startTimestamp; + uint64 duration; + } + + /// EXTERNAL FUNCTIONS /// + + /** + * @notice Creates a new range payment on behalf of an AVS, to be split amongst the + * set of stakers delegated to operators who are registered to the `avs` + * @param rangePayments The range payments being created + * @dev Expected to be called by the ServiceManager of the AVS on behalf of which the payment is being made + * @dev The duration of the `rangePayment` cannot exceed `MAX_PAYMENT_DURATION` + * @dev The tokens are sent to the `claimingManager` contract + * @dev This function will revert if the `rangePayment` is malformed, + * e.g. if the `strategies` and `weights` arrays are of non-equal lengths + */ + function payForRange(RangePayment[] calldata rangePayments) external; +} diff --git a/src/interfaces/avs/vendored/IServiceManager.sol b/src/interfaces/avs/vendored/IServiceManager.sol new file mode 100755 index 0000000..2393fc6 --- /dev/null +++ b/src/interfaces/avs/vendored/IServiceManager.sol @@ -0,0 +1,28 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity >=0.8.0; + +import {IPaymentCoordinator} from "./IPaymentCoordinator.sol"; +import {IServiceManagerUI} from "./IServiceManagerUI.sol"; + +/** + * @title Minimal interface for a ServiceManager-type contract that forms the single point for an AVS to push updates to EigenLayer + * @author Layr Labs, Inc. + */ +interface IServiceManager is IServiceManagerUI { + /** + * @notice Creates a new range payment on behalf of an AVS, to be split amongst the + * set of stakers delegated to operators who are registered to the `avs`. + * Note that the owner calling this function must have approved the tokens to be transferred to the ServiceManager + * and of course has the required balances. + * @param rangePayments The range payments being created + * @dev Expected to be called by the ServiceManager of the AVS on behalf of which the payment is being made + * @dev The duration of the `rangePayment` cannot exceed `paymentCoordinator.MAX_PAYMENT_DURATION()` + * @dev The tokens are sent to the `PaymentCoordinator` contract + * @dev Strategies must be in ascending order of addresses to check for duplicates + * @dev This function will revert if the `rangePayment` is malformed, + * e.g. if the `strategies` and `weights` arrays are of non-equal lengths + */ + function payForRange( + IPaymentCoordinator.RangePayment[] calldata rangePayments + ) external; +} diff --git a/src/interfaces/avs/vendored/IServiceManagerUI.sol b/src/interfaces/avs/vendored/IServiceManagerUI.sol new file mode 100755 index 0000000..8df18a4 --- /dev/null +++ b/src/interfaces/avs/vendored/IServiceManagerUI.sol @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity >=0.8.0; + +import {ISignatureUtils} from "./ISignatureUtils.sol"; +import {IDelegationManager} from "./IDelegationManager.sol"; + +/** + * @title Minimal interface for a ServiceManager-type contract that AVS ServiceManager contracts must implement + * for eigenlabs to be able to index their data on the AVS marketplace frontend. + * @author Layr Labs, Inc. + */ +interface IServiceManagerUI { + /** + * Metadata should follow the format outlined by this example. + * { + * "name": "EigenLabs AVS 1", + * "website": "https://www.eigenlayer.xyz/", + * "description": "This is my 1st AVS", + * "logo": "https://holesky-operator-metadata.s3.amazonaws.com/eigenlayer.png", + * "twitter": "https://twitter.com/eigenlayer" + * } + * @notice Updates the metadata URI for the AVS + * @param _metadataURI is the metadata URI for the AVS + */ + function updateAVSMetadataURI(string memory _metadataURI) external; + + /** + * @notice Forwards a call to EigenLayer's DelegationManager contract to confirm operator registration with the AVS + * @param operator The address of the operator to register. + * @param operatorSignature The signature, salt, and expiry of the operator's signature. + */ + function registerOperatorToAVS( + address operator, + ISignatureUtils.SignatureWithSaltAndExpiry memory operatorSignature + ) external; + + /** + * @notice Forwards a call to EigenLayer's DelegationManager contract to confirm operator deregistration from the AVS + * @param operator The address of the operator to deregister. + */ + function deregisterOperatorFromAVS(address operator) external; + + /** + * @notice Returns the list of strategies that the operator has potentially restaked on the AVS + * @param operator The address of the operator to get restaked strategies for + * @dev This function is intended to be called off-chain + * @dev No guarantee is made on whether the operator has shares for a strategy in a quorum or uniqueness + * of each element in the returned array. The off-chain service should do that validation separately + */ + function getOperatorRestakedStrategies( + address operator + ) external view returns (address[] memory); + + /** + * @notice Returns the list of strategies that the AVS supports for restaking + * @dev This function is intended to be called off-chain + * @dev No guarantee is made on uniqueness of each element in the returned array. + * The off-chain service should do that validation separately + */ + function getRestakeableStrategies() + external + view + returns (address[] memory); + + /// @notice Returns the EigenLayer AVSDirectory contract. + function avsDirectory() external view returns (address); +} diff --git a/src/interfaces/avs/vendored/ISignatureUtils.sol b/src/interfaces/avs/vendored/ISignatureUtils.sol new file mode 100755 index 0000000..158b325 --- /dev/null +++ b/src/interfaces/avs/vendored/ISignatureUtils.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity >=0.5.0; + +/** + * @title The interface for common signature utilities. + * @author Layr Labs, Inc. + * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service + */ +interface ISignatureUtils { + // @notice Struct that bundles together a signature and an expiration time for the signature. Used primarily for stack management. + struct SignatureWithExpiry { + // the signature itself, formatted as a single bytes object + bytes signature; + // the expiration timestamp (UTC) of the signature + uint256 expiry; + } + + // @notice Struct that bundles together a signature, a salt for uniqueness, and an expiration time for the signature. Used primarily for stack management. + struct SignatureWithSaltAndExpiry { + // the signature itself, formatted as a single bytes object + bytes signature; + // the salt used to generate the signature + bytes32 salt; + // the expiration timestamp (UTC) of the signature + uint256 expiry; + } +} diff --git a/src/interfaces/avs/vendored/ISlasher.sol b/src/interfaces/avs/vendored/ISlasher.sol new file mode 100755 index 0000000..577a36e --- /dev/null +++ b/src/interfaces/avs/vendored/ISlasher.sol @@ -0,0 +1,11 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity >=0.5.0; + +/** + * @title Interface for the primary 'slashing' contract for EigenLayer. + * @author Layr Labs, Inc. + * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service + */ +interface ISlasher { + function freezeOperator(address toBeFrozen) external; +} diff --git a/src/interfaces/avs/vendored/IStrategy.sol b/src/interfaces/avs/vendored/IStrategy.sol new file mode 100755 index 0000000..3bcc517 --- /dev/null +++ b/src/interfaces/avs/vendored/IStrategy.sol @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: BUSL-1.1 +pragma solidity >=0.5.0; + +import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; + +/** + * @title Minimal interface for an `Strategy` contract. + * @author Layr Labs, Inc. + * @notice Terms of Service: https://docs.eigenlayer.xyz/overview/terms-of-service + * @notice Custom `Strategy` implementations may expand extensively on this interface. + */ +interface IStrategy { + /** + * @notice Used to deposit tokens into this Strategy + * @param token is the ERC20 token being deposited + * @param amount is the amount of token being deposited + * @dev This function is only callable by the strategyManager contract. It is invoked inside of the strategyManager's + * `depositIntoStrategy` function, and individual share balances are recorded in the strategyManager as well. + * @return newShares is the number of new shares issued at the current exchange ratio. + */ + function deposit(IERC20 token, uint256 amount) external returns (uint256); + + /** + * @notice Used to withdraw tokens from this Strategy, to the `recipient`'s address + * @param recipient is the address to receive the withdrawn funds + * @param token is the ERC20 token being transferred out + * @param amountShares is the amount of shares being withdrawn + * @dev This function is only callable by the strategyManager contract. It is invoked inside of the strategyManager's + * other functions, and individual share balances are recorded in the strategyManager as well. + */ + function withdraw( + address recipient, + IERC20 token, + uint256 amountShares + ) external; + + /** + * @notice Used to convert a number of shares to the equivalent amount of underlying tokens for this strategy. + * @notice In contrast to `sharesToUnderlyingView`, this function **may** make state modifications + * @param amountShares is the amount of shares to calculate its conversion into the underlying token + * @return The amount of underlying tokens corresponding to the input `amountShares` + * @dev Implementation for these functions in particular may vary significantly for different strategies + */ + function sharesToUnderlying( + uint256 amountShares + ) external returns (uint256); + + /** + * @notice Used to convert an amount of underlying tokens to the equivalent amount of shares in this strategy. + * @notice In contrast to `underlyingToSharesView`, this function **may** make state modifications + * @param amountUnderlying is the amount of `underlyingToken` to calculate its conversion into strategy shares + * @return The amount of underlying tokens corresponding to the input `amountShares` + * @dev Implementation for these functions in particular may vary significantly for different strategies + */ + function underlyingToShares( + uint256 amountUnderlying + ) external returns (uint256); + + /** + * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in + * this strategy. In contrast to `userUnderlyingView`, this function **may** make state modifications + */ + function userUnderlying(address user) external returns (uint256); + + /** + * @notice convenience function for fetching the current total shares of `user` in this strategy, by + * querying the `strategyManager` contract + */ + function shares(address user) external view returns (uint256); + + /** + * @notice Used to convert a number of shares to the equivalent amount of underlying tokens for this strategy. + * @notice In contrast to `sharesToUnderlying`, this function guarantees no state modifications + * @param amountShares is the amount of shares to calculate its conversion into the underlying token + * @return The amount of shares corresponding to the input `amountUnderlying` + * @dev Implementation for these functions in particular may vary significantly for different strategies + */ + function sharesToUnderlyingView( + uint256 amountShares + ) external view returns (uint256); + + /** + * @notice Used to convert an amount of underlying tokens to the equivalent amount of shares in this strategy. + * @notice In contrast to `underlyingToShares`, this function guarantees no state modifications + * @param amountUnderlying is the amount of `underlyingToken` to calculate its conversion into strategy shares + * @return The amount of shares corresponding to the input `amountUnderlying` + * @dev Implementation for these functions in particular may vary significantly for different strategies + */ + function underlyingToSharesView( + uint256 amountUnderlying + ) external view returns (uint256); + + /** + * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in + * this strategy. In contrast to `userUnderlying`, this function guarantees no state modifications + */ + function userUnderlyingView(address user) external view returns (uint256); + + /// @notice The underlying token for shares in this Strategy + function underlyingToken() external view returns (IERC20); + + /// @notice The total number of extant shares in this Strategy + function totalShares() external view returns (uint256); + + /// @notice Returns either a brief string explaining the strategy's goal & purpose, or a link to metadata that explains in more detail. + function explanation() external view returns (string memory); +} diff --git a/src/tokens/Native.sol b/src/tokens/Native.sol deleted file mode 100755 index 8269e7c..0000000 --- a/src/tokens/Native.sol +++ /dev/null @@ -1,77 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity >=0.8.0; - -import {TokenRouter} from "./libs/TokenRouter.sol"; -import {TokenMessage} from "./libs/TokenMessage.sol"; -import {Address} from "@openzeppelin/contracts/utils/Address.sol"; - -/** - * @title Native Token Router that extends ERC20 with remote transfer functionality. - * @author Abacus Works - * @dev Supply on each chain is not constant but the aggregate supply across all chains is. - */ -contract ManifoldNative is TokenRouter { - /** - * @dev Emitted when native tokens are donated to the contract. - * @param sender The address of the sender. - * @param amount The amount of native tokens donated. - */ - event Donation(address indexed sender, uint256 amount); - - constructor(address _mailbox) TokenRouter(_mailbox) {} - - /** - * @notice Initializes the Token router - * @param _hook The post-dispatch hook contract. - * @param _interchainSecurityModule The interchain security module contract. - * @param _owner The this contract. - */ - function initialize(address _hook, address _interchainSecurityModule, address _owner) public initializer { - _MailboxClient_initialize(_hook, _interchainSecurityModule, _owner); - } - - /** - * @inheritdoc TokenRouter - * @dev uses (`msg.value` - `_amount`) as hook payment and `msg.sender` as refund address. - */ - function transferRemote(uint32 _destination, bytes32 _recipient, uint256 _amount) - external - payable - virtual - override - returns (bytes32 messageId) - { - require(msg.value >= _amount, "Native: amount exceeds msg.value"); - uint256 _hookPayment = msg.value - _amount; - return _transferRemote(_destination, _recipient, _amount, _hookPayment); - } - - function balanceOf(address _account) external view override returns (uint256) { - return _account.balance; - } - - /** - * @inheritdoc TokenRouter - * @dev No-op because native amount is transferred in `msg.value` - * @dev Compiler will not include this in the bytecode. - */ - function _transferFromSender(uint256) internal pure override returns (bytes memory) { - return bytes(""); // no metadata - } - - /** - * @dev Sends `_amount` of native token to `_recipient` balance. - * @inheritdoc TokenRouter - */ - function _transferTo( - address _recipient, - uint256 _amount, - bytes calldata // no metadata - ) internal virtual override { - Address.sendValue(payable(_recipient), _amount); - } - - receive() external payable { - emit Donation(msg.sender, msg.value); - } -} diff --git a/src/tokens/extensions/ManifoldERC20.sol b/src/tokens/extensions/ManifoldERC20.sol deleted file mode 100755 index 6f25678..0000000 --- a/src/tokens/extensions/ManifoldERC20.sol +++ /dev/null @@ -1,49 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -pragma solidity >=0.8.0; - -import {ManifoldERC20} from "../ManifoldERC20.sol"; -import {FastTokenRouter} from "../libs/FastTokenRouter.sol"; -import {TokenRouter} from "../libs/TokenRouter.sol"; - -import {ERC20Upgradeable} from "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; - -/** - * @title ERC20 Token Router that extends ERC20 with remote transfer functionality. - * @author Abacus Works - * @dev Supply on each chain is not constant but the aggregate supply across all chains is. - */ -contract FastManifoldERC20 is FastTokenRouter, ManifoldERC20 { - constructor(uint8 __decimals, address _mailbox) ManifoldERC20(__decimals, _mailbox) {} - - /** - * @dev delegates transfer logic to `_transferTo`. - * @inheritdoc TokenRouter - */ - function _handle(uint32 _origin, bytes32 _sender, bytes calldata _message) - internal - virtual - override(FastTokenRouter, TokenRouter) - { - FastTokenRouter._handle(_origin, _sender, _message); - } - - /** - * @dev Mints `_amount` of tokens to `_recipient`. - * @inheritdoc FastTokenRouter - */ - function _fastTransferTo(address _recipient, uint256 _amount) internal override { - _mint(_recipient, _amount); - } - - /** - * @dev Burns `_amount` of tokens from `_recipient`. - * @inheritdoc FastTokenRouter - */ - function _fastRecieveFrom(address _sender, uint256 _amount) internal override { - _burn(_sender, _amount); - } - - function balanceOf(address _account) public view virtual override(ManifoldERC20, TokenRouter) returns (uint256) { - return ERC20Upgradeable.balanceOf(_account); - } -} From f6def5ee3bfa65dfe7fc78d94dcd01bcd64283f5 Mon Sep 17 00:00:00 2001 From: sam bacha Date: Thu, 15 Aug 2024 22:49:36 -0700 Subject: [PATCH 7/8] refactor(imports0: map and set --- foundry.toml | 143 ------- src/libs/EnumerableMap.sol | 533 +++++++++++++++++++++++++++ src/libs/EnumerableMapEnrollment.sol | 4 +- src/libs/EnumerableSet.sol | 378 +++++++++++++++++++ 4 files changed, 913 insertions(+), 145 deletions(-) delete mode 100644 foundry.toml create mode 100644 src/libs/EnumerableMap.sol create mode 100644 src/libs/EnumerableSet.sol diff --git a/foundry.toml b/foundry.toml deleted file mode 100644 index 5d0bde6..0000000 --- a/foundry.toml +++ /dev/null @@ -1,143 +0,0 @@ -[profile.default] -src = "src" -test = "test" -script = "script" -out = "out" -libs = ["lib"] -remappings = [ - "@openzeppelin-upgrades/=/lib/openzeppelin-contracts-upgradeable/contracts/", - "@openzeppelin=/lib/openzeppelin-contracts/contracts/", - "ds-test/=lib/eigenlayer-middleware/lib/ds-test/src/", - "eigenlayer-contracts/=lib/eigenlayer-middleware/lib/eigenlayer-contracts/", - "eigenlayer-middleware/=lib/eigenlayer-middleware/src/", - "forge-std/=lib/eigenlayer-middleware/lib/forge-std/src/", -] -auto_detect_remappings = true -libraries = [] -cache = true -cache_path = "cache" -broadcast = "broadcast" -allow_paths = [] -include_paths = [] -skip = [] -force = false -evm_version = "paris" -gas_reports = ["*"] -gas_reports_ignore = [] -auto_detect_solc = true -offline = false -optimizer = true -optimizer_runs = 200 -verbosity = 0 -ignored_error_codes = [ - "license", - "code-size", - "init-code-size", - "transient-storage", -] -ignored_warnings_from = [] -deny_warnings = false -test_failures_file = "cache/test-failures" -show_progress = false -unchecked_cheatcode_artifacts = false -create2_library_salt = "0x0000000000000000000000000000000000000000000000000000000000000000" -ffi = false -always_use_create_2_factory = false -prompt_timeout = 120 -sender = "0x1804c8ab1f12e6bbf3894d4083f33e07309d1f38" -tx_origin = "0x1804c8ab1f12e6bbf3894d4083f33e07309d1f38" -initial_balance = "0xffffffffffffffffffffffff" -block_number = 1 -gas_limit = 1073741824 -block_base_fee_per_gas = 0 -block_coinbase = "0x0000000000000000000000000000000000000000" -block_timestamp = 1 -block_difficulty = 0 -block_prevrandao = "0x0000000000000000000000000000000000000000000000000000000000000000" -memory_limit = 134217728 -extra_output = [] -extra_output_files = [] -names = false -sizes = false -via_ir = false -ast = false -no_storage_caching = false -no_rpc_rate_limit = false -use_literal_content = false -bytecode_hash = "ipfs" -cbor_metadata = true -sparse_mode = false -build_info = false -legacy_assertions = false -assertions_revert = true -disable_block_gas_limit = false -isolate = false - -[[profile.default.fs_permissions]] -access = "read" -path = "out" - -[profile.default.rpc_storage_caching] -chains = "all" -endpoints = "all" - -[fmt] -line_length = 120 -tab_width = 4 -bracket_spacing = false -int_types = "long" -multiline_func_header = "attributes_first" -quote_style = "double" -number_underscore = "preserve" -hex_underscore = "remove" -single_line_statement_blocks = "preserve" -override_spacing = false -wrap_comments = false -ignore = [] -contract_new_lines = false -sort_imports = false - -[doc] -out = "docs" -title = "" -book = "book.toml" -homepage = "README.md" -ignore = [] - -[fuzz] -runs = 256 -max_test_rejects = 65536 -dictionary_weight = 40 -include_storage = true -include_push_bytes = true -max_fuzz_dictionary_addresses = 15728640 -max_fuzz_dictionary_values = 6553600 -gas_report_samples = 256 -failure_persist_dir = "cache/fuzz" -failure_persist_file = "failures" -show_logs = false - -[invariant] -runs = 256 -depth = 500 -fail_on_revert = false -call_override = false -dictionary_weight = 80 -include_storage = true -include_push_bytes = true -max_fuzz_dictionary_addresses = 15728640 -max_fuzz_dictionary_values = 6553600 -shrink_run_limit = 5000 -max_assume_rejects = 65536 -gas_report_samples = 256 -failure_persist_dir = "cache/invariant" - -[labels] - -[vyper] - -[bind_json] -out = "utils/JsonBindings.sol" -include = [] -exclude = [] - diff --git a/src/libs/EnumerableMap.sol b/src/libs/EnumerableMap.sol new file mode 100644 index 0000000..929ae7c --- /dev/null +++ b/src/libs/EnumerableMap.sol @@ -0,0 +1,533 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableMap.sol) +// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js. + +pragma solidity ^0.8.20; + +import {EnumerableSet} from "./EnumerableSet.sol"; + +/** + * @dev Library for managing an enumerable variant of Solidity's + * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`] + * type. + * + * Maps have the following properties: + * + * - Entries are added, removed, and checked for existence in constant time + * (O(1)). + * - Entries are enumerated in O(n). No guarantees are made on the ordering. + * + * ```solidity + * contract Example { + * // Add the library methods + * using EnumerableMap for EnumerableMap.UintToAddressMap; + * + * // Declare a set state variable + * EnumerableMap.UintToAddressMap private myMap; + * } + * ``` + * + * The following map types are supported: + * + * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0 + * - `address -> uint256` (`AddressToUintMap`) since v4.6.0 + * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0 + * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0 + * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0 + * + * [WARNING] + * ==== + * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure + * unusable. + * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. + * + * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an + * array of EnumerableMap. + * ==== + */ +library EnumerableMap { + using EnumerableSet for EnumerableSet.Bytes32Set; + + // To implement this library for multiple types with as little code repetition as possible, we write it in + // terms of a generic Map type with bytes32 keys and values. The Map implementation uses private functions, + // and user-facing implementations such as `UintToAddressMap` are just wrappers around the underlying Map. + // This means that we can only create new EnumerableMaps for types that fit in bytes32. + + /** + * @dev Query for a nonexistent map key. + */ + error EnumerableMapNonexistentKey(bytes32 key); + + struct Bytes32ToBytes32Map { + // Storage of keys + EnumerableSet.Bytes32Set _keys; + mapping(bytes32 key => bytes32) _values; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) { + map._values[key] = value; + return map._keys.add(key); + } + + /** + * @dev Removes a key-value pair from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) { + delete map._values[key]; + return map._keys.remove(key); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) { + return map._keys.contains(key); + } + + /** + * @dev Returns the number of key-value pairs in the map. O(1). + */ + function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) { + return map._keys.length(); + } + + /** + * @dev Returns the key-value pair stored at position `index` in the map. O(1). + * + * Note that there are no guarantees on the ordering of entries inside the + * array, and it may change when more entries are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) { + bytes32 key = map._keys.at(index); + return (key, map._values[key]); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) { + bytes32 value = map._values[key]; + if (value == bytes32(0)) { + return (contains(map, key), bytes32(0)); + } else { + return (true, value); + } + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) { + bytes32 value = map._values[key]; + if (value == 0 && !contains(map, key)) { + revert EnumerableMapNonexistentKey(key); + } + return value; + } + + /** + * @dev Return the an array containing all the keys + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) { + return map._keys.values(); + } + + // UintToUintMap + + struct UintToUintMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) { + return set(map._inner, bytes32(key), bytes32(value)); + } + + /** + * @dev Removes a value from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(UintToUintMap storage map, uint256 key) internal returns (bool) { + return remove(map._inner, bytes32(key)); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) { + return contains(map._inner, bytes32(key)); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(UintToUintMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the map. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (uint256(key), uint256(value)); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) { + (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); + return (success, uint256(value)); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) { + return uint256(get(map._inner, bytes32(key))); + } + + /** + * @dev Return the an array containing all the keys + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function keys(UintToUintMap storage map) internal view returns (uint256[] memory) { + bytes32[] memory store = keys(map._inner); + uint256[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // UintToAddressMap + + struct UintToAddressMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) { + return set(map._inner, bytes32(key), bytes32(uint256(uint160(value)))); + } + + /** + * @dev Removes a value from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) { + return remove(map._inner, bytes32(key)); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) { + return contains(map._inner, bytes32(key)); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(UintToAddressMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the map. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (uint256(key), address(uint160(uint256(value)))); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) { + (bool success, bytes32 value) = tryGet(map._inner, bytes32(key)); + return (success, address(uint160(uint256(value)))); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(UintToAddressMap storage map, uint256 key) internal view returns (address) { + return address(uint160(uint256(get(map._inner, bytes32(key))))); + } + + /** + * @dev Return the an array containing all the keys + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) { + bytes32[] memory store = keys(map._inner); + uint256[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // AddressToUintMap + + struct AddressToUintMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) { + return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value)); + } + + /** + * @dev Removes a value from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(AddressToUintMap storage map, address key) internal returns (bool) { + return remove(map._inner, bytes32(uint256(uint160(key)))); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(AddressToUintMap storage map, address key) internal view returns (bool) { + return contains(map._inner, bytes32(uint256(uint160(key)))); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(AddressToUintMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the map. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (address(uint160(uint256(key))), uint256(value)); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) { + (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key)))); + return (success, uint256(value)); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(AddressToUintMap storage map, address key) internal view returns (uint256) { + return uint256(get(map._inner, bytes32(uint256(uint160(key))))); + } + + /** + * @dev Return the an array containing all the keys + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function keys(AddressToUintMap storage map) internal view returns (address[] memory) { + bytes32[] memory store = keys(map._inner); + address[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // Bytes32ToUintMap + + struct Bytes32ToUintMap { + Bytes32ToBytes32Map _inner; + } + + /** + * @dev Adds a key-value pair to a map, or updates the value for an existing + * key. O(1). + * + * Returns true if the key was added to the map, that is if it was not + * already present. + */ + function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) { + return set(map._inner, key, bytes32(value)); + } + + /** + * @dev Removes a value from a map. O(1). + * + * Returns true if the key was removed from the map, that is if it was present. + */ + function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) { + return remove(map._inner, key); + } + + /** + * @dev Returns true if the key is in the map. O(1). + */ + function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) { + return contains(map._inner, key); + } + + /** + * @dev Returns the number of elements in the map. O(1). + */ + function length(Bytes32ToUintMap storage map) internal view returns (uint256) { + return length(map._inner); + } + + /** + * @dev Returns the element stored at position `index` in the map. O(1). + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) { + (bytes32 key, bytes32 value) = at(map._inner, index); + return (key, uint256(value)); + } + + /** + * @dev Tries to returns the value associated with `key`. O(1). + * Does not revert if `key` is not in the map. + */ + function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) { + (bool success, bytes32 value) = tryGet(map._inner, key); + return (success, uint256(value)); + } + + /** + * @dev Returns the value associated with `key`. O(1). + * + * Requirements: + * + * - `key` must be in the map. + */ + function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) { + return uint256(get(map._inner, key)); + } + + /** + * @dev Return the an array containing all the keys + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) { + bytes32[] memory store = keys(map._inner); + bytes32[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } +} diff --git a/src/libs/EnumerableMapEnrollment.sol b/src/libs/EnumerableMapEnrollment.sol index 66a4b0b..954cb21 100644 --- a/src/libs/EnumerableMapEnrollment.sol +++ b/src/libs/EnumerableMapEnrollment.sol @@ -2,8 +2,8 @@ pragma solidity >=0.6.11; // ============ External Imports ============ -import "@openzeppelin/contracts/utils/structs/EnumerableMap.sol"; -import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol"; +import "./EnumerableMap.sol"; +import "./EnumerableSet.sol"; // ============ Internal Imports ============ import {TypeCasts} from "./TypeCasts.sol"; diff --git a/src/libs/EnumerableSet.sol b/src/libs/EnumerableSet.sol new file mode 100644 index 0000000..4c7fc5e --- /dev/null +++ b/src/libs/EnumerableSet.sol @@ -0,0 +1,378 @@ +// SPDX-License-Identifier: MIT +// OpenZeppelin Contracts (last updated v5.0.0) (utils/structs/EnumerableSet.sol) +// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js. + +pragma solidity ^0.8.20; + +/** + * @dev Library for managing + * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive + * types. + * + * Sets have the following properties: + * + * - Elements are added, removed, and checked for existence in constant time + * (O(1)). + * - Elements are enumerated in O(n). No guarantees are made on the ordering. + * + * ```solidity + * contract Example { + * // Add the library methods + * using EnumerableSet for EnumerableSet.AddressSet; + * + * // Declare a set state variable + * EnumerableSet.AddressSet private mySet; + * } + * ``` + * + * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) + * and `uint256` (`UintSet`) are supported. + * + * [WARNING] + * ==== + * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure + * unusable. + * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info. + * + * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an + * array of EnumerableSet. + * ==== + */ +library EnumerableSet { + // To implement this library for multiple types with as little code + // repetition as possible, we write it in terms of a generic Set type with + // bytes32 values. + // The Set implementation uses private functions, and user-facing + // implementations (such as AddressSet) are just wrappers around the + // underlying Set. + // This means that we can only create new EnumerableSets for types that fit + // in bytes32. + + struct Set { + // Storage of set values + bytes32[] _values; + // Position is the index of the value in the `values` array plus 1. + // Position 0 is used to mean a value is not in the set. + mapping(bytes32 value => uint256) _positions; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function _add(Set storage set, bytes32 value) private returns (bool) { + if (!_contains(set, value)) { + set._values.push(value); + // The value is stored at length-1, but we add 1 to all indexes + // and use 0 as a sentinel value + set._positions[value] = set._values.length; + return true; + } else { + return false; + } + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function _remove(Set storage set, bytes32 value) private returns (bool) { + // We cache the value's position to prevent multiple reads from the same storage slot + uint256 position = set._positions[value]; + + if (position != 0) { + // Equivalent to contains(set, value) + // To delete an element from the _values array in O(1), we swap the element to delete with the last one in + // the array, and then remove the last element (sometimes called as 'swap and pop'). + // This modifies the order of the array, as noted in {at}. + + uint256 valueIndex = position - 1; + uint256 lastIndex = set._values.length - 1; + + if (valueIndex != lastIndex) { + bytes32 lastValue = set._values[lastIndex]; + + // Move the lastValue to the index where the value to delete is + set._values[valueIndex] = lastValue; + // Update the tracked position of the lastValue (that was just moved) + set._positions[lastValue] = position; + } + + // Delete the slot where the moved value was stored + set._values.pop(); + + // Delete the tracked position for the deleted slot + delete set._positions[value]; + + return true; + } else { + return false; + } + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function _contains(Set storage set, bytes32 value) private view returns (bool) { + return set._positions[value] != 0; + } + + /** + * @dev Returns the number of values on the set. O(1). + */ + function _length(Set storage set) private view returns (uint256) { + return set._values.length; + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function _at(Set storage set, uint256 index) private view returns (bytes32) { + return set._values[index]; + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function _values(Set storage set) private view returns (bytes32[] memory) { + return set._values; + } + + // Bytes32Set + + struct Bytes32Set { + Set _inner; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { + return _add(set._inner, value); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { + return _remove(set._inner, value); + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { + return _contains(set._inner, value); + } + + /** + * @dev Returns the number of values in the set. O(1). + */ + function length(Bytes32Set storage set) internal view returns (uint256) { + return _length(set._inner); + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { + return _at(set._inner, index); + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function values(Bytes32Set storage set) internal view returns (bytes32[] memory) { + bytes32[] memory store = _values(set._inner); + bytes32[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // AddressSet + + struct AddressSet { + Set _inner; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function add(AddressSet storage set, address value) internal returns (bool) { + return _add(set._inner, bytes32(uint256(uint160(value)))); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function remove(AddressSet storage set, address value) internal returns (bool) { + return _remove(set._inner, bytes32(uint256(uint160(value)))); + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function contains(AddressSet storage set, address value) internal view returns (bool) { + return _contains(set._inner, bytes32(uint256(uint160(value)))); + } + + /** + * @dev Returns the number of values in the set. O(1). + */ + function length(AddressSet storage set) internal view returns (uint256) { + return _length(set._inner); + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(AddressSet storage set, uint256 index) internal view returns (address) { + return address(uint160(uint256(_at(set._inner, index)))); + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function values(AddressSet storage set) internal view returns (address[] memory) { + bytes32[] memory store = _values(set._inner); + address[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } + + // UintSet + + struct UintSet { + Set _inner; + } + + /** + * @dev Add a value to a set. O(1). + * + * Returns true if the value was added to the set, that is if it was not + * already present. + */ + function add(UintSet storage set, uint256 value) internal returns (bool) { + return _add(set._inner, bytes32(value)); + } + + /** + * @dev Removes a value from a set. O(1). + * + * Returns true if the value was removed from the set, that is if it was + * present. + */ + function remove(UintSet storage set, uint256 value) internal returns (bool) { + return _remove(set._inner, bytes32(value)); + } + + /** + * @dev Returns true if the value is in the set. O(1). + */ + function contains(UintSet storage set, uint256 value) internal view returns (bool) { + return _contains(set._inner, bytes32(value)); + } + + /** + * @dev Returns the number of values in the set. O(1). + */ + function length(UintSet storage set) internal view returns (uint256) { + return _length(set._inner); + } + + /** + * @dev Returns the value stored at position `index` in the set. O(1). + * + * Note that there are no guarantees on the ordering of values inside the + * array, and it may change when more values are added or removed. + * + * Requirements: + * + * - `index` must be strictly less than {length}. + */ + function at(UintSet storage set, uint256 index) internal view returns (uint256) { + return uint256(_at(set._inner, index)); + } + + /** + * @dev Return the entire set in an array + * + * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed + * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that + * this function has an unbounded cost, and using it as part of a state-changing function may render the function + * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block. + */ + function values(UintSet storage set) internal view returns (uint256[] memory) { + bytes32[] memory store = _values(set._inner); + uint256[] memory result; + + /// @solidity memory-safe-assembly + assembly { + result := store + } + + return result; + } +} From eefb3c28257808ed80be1eb8e68be743dc808c3c Mon Sep 17 00:00:00 2001 From: sam bacha Date: Thu, 15 Aug 2024 22:49:51 -0700 Subject: [PATCH 8/8] fix(fmt): lint --- src/interfaces/avs/IRemoteChallenger.sol | 3 +-- .../avs/vendored/IDelegationManager.sol | 19 ++++++---------- .../IECDSAStakeRegistryEventsAndErrors.sol | 16 +++----------- .../avs/vendored/IServiceManager.sol | 4 +--- .../avs/vendored/IServiceManagerUI.sol | 9 ++------ src/interfaces/avs/vendored/IStrategy.sol | 22 +++++-------------- 6 files changed, 19 insertions(+), 54 deletions(-) diff --git a/src/interfaces/avs/IRemoteChallenger.sol b/src/interfaces/avs/IRemoteChallenger.sol index 4270031..0135782 100644 --- a/src/interfaces/avs/IRemoteChallenger.sol +++ b/src/interfaces/avs/IRemoteChallenger.sol @@ -1,7 +1,6 @@ // SPDX-License-Identifier: MIT OR Apache-2.0 pragma solidity >=0.8.0; - interface IRemoteChallenger { /// @notice Returns the number of blocks that must be mined before a challenge can be handled /// @return The number of blocks that must be mined before a challenge can be handled @@ -10,4 +9,4 @@ interface IRemoteChallenger { /// @notice Handles a challenge for an operator /// @param operator The address of the operator function handleChallenge(address operator) external; -} \ No newline at end of file +} diff --git a/src/interfaces/avs/vendored/IDelegationManager.sol b/src/interfaces/avs/vendored/IDelegationManager.sol index 50fe929..09f651c 100755 --- a/src/interfaces/avs/vendored/IDelegationManager.sol +++ b/src/interfaces/avs/vendored/IDelegationManager.sol @@ -20,18 +20,13 @@ interface IDelegationManager { uint32 stakerOptOutWindowBlocks; } - event OperatorMetadataURIUpdated( - address indexed operator, - string metadataURI - ); + event OperatorMetadataURIUpdated(address indexed operator, string metadataURI); - function registerAsOperator( - OperatorDetails calldata registeringOperatorDetails, - string calldata metadataURI - ) external; + function registerAsOperator(OperatorDetails calldata registeringOperatorDetails, string calldata metadataURI) + external; - function getOperatorShares( - address operator, - IStrategy[] memory strategies - ) external view returns (uint256[] memory); + function getOperatorShares(address operator, IStrategy[] memory strategies) + external + view + returns (uint256[] memory); } diff --git a/src/interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol b/src/interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol index 07f6323..edaec81 100755 --- a/src/interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol +++ b/src/interfaces/avs/vendored/IECDSAStakeRegistryEventsAndErrors.sol @@ -36,20 +36,13 @@ interface IECDSAStakeRegistryEventsAndErrors { /// @notice Emitted when the weight required to be an operator changes /// @param oldMinimumWeight The previous weight /// @param newMinimumWeight The updated weight - event UpdateMinimumWeight( - uint256 oldMinimumWeight, - uint256 newMinimumWeight - ); + event UpdateMinimumWeight(uint256 oldMinimumWeight, uint256 newMinimumWeight); /// @notice Emitted when the system updates an operator's weight /// @param _operator The address of the operator updated /// @param oldWeight The operator's weight before the update /// @param newWeight The operator's weight after the update - event OperatorWeightUpdated( - address indexed _operator, - uint256 oldWeight, - uint256 newWeight - ); + event OperatorWeightUpdated(address indexed _operator, uint256 oldWeight, uint256 newWeight); /// @notice Emitted when the system updates the total weight /// @param oldTotalWeight The total weight before the update @@ -65,10 +58,7 @@ interface IECDSAStakeRegistryEventsAndErrors { /// @param newSigningKey The operator's signing key after the update /// @param oldSigningKey The operator's signing key before the update event SigningKeyUpdate( - address indexed operator, - uint256 indexed updateBlock, - address indexed newSigningKey, - address oldSigningKey + address indexed operator, uint256 indexed updateBlock, address indexed newSigningKey, address oldSigningKey ); /// @notice Indicates when the lengths of the signers array and signatures array do not match. diff --git a/src/interfaces/avs/vendored/IServiceManager.sol b/src/interfaces/avs/vendored/IServiceManager.sol index 2393fc6..565c558 100755 --- a/src/interfaces/avs/vendored/IServiceManager.sol +++ b/src/interfaces/avs/vendored/IServiceManager.sol @@ -22,7 +22,5 @@ interface IServiceManager is IServiceManagerUI { * @dev This function will revert if the `rangePayment` is malformed, * e.g. if the `strategies` and `weights` arrays are of non-equal lengths */ - function payForRange( - IPaymentCoordinator.RangePayment[] calldata rangePayments - ) external; + function payForRange(IPaymentCoordinator.RangePayment[] calldata rangePayments) external; } diff --git a/src/interfaces/avs/vendored/IServiceManagerUI.sol b/src/interfaces/avs/vendored/IServiceManagerUI.sol index 8df18a4..390237c 100755 --- a/src/interfaces/avs/vendored/IServiceManagerUI.sol +++ b/src/interfaces/avs/vendored/IServiceManagerUI.sol @@ -47,9 +47,7 @@ interface IServiceManagerUI { * @dev No guarantee is made on whether the operator has shares for a strategy in a quorum or uniqueness * of each element in the returned array. The off-chain service should do that validation separately */ - function getOperatorRestakedStrategies( - address operator - ) external view returns (address[] memory); + function getOperatorRestakedStrategies(address operator) external view returns (address[] memory); /** * @notice Returns the list of strategies that the AVS supports for restaking @@ -57,10 +55,7 @@ interface IServiceManagerUI { * @dev No guarantee is made on uniqueness of each element in the returned array. * The off-chain service should do that validation separately */ - function getRestakeableStrategies() - external - view - returns (address[] memory); + function getRestakeableStrategies() external view returns (address[] memory); /// @notice Returns the EigenLayer AVSDirectory contract. function avsDirectory() external view returns (address); diff --git a/src/interfaces/avs/vendored/IStrategy.sol b/src/interfaces/avs/vendored/IStrategy.sol index 3bcc517..5db9a97 100755 --- a/src/interfaces/avs/vendored/IStrategy.sol +++ b/src/interfaces/avs/vendored/IStrategy.sol @@ -28,11 +28,7 @@ interface IStrategy { * @dev This function is only callable by the strategyManager contract. It is invoked inside of the strategyManager's * other functions, and individual share balances are recorded in the strategyManager as well. */ - function withdraw( - address recipient, - IERC20 token, - uint256 amountShares - ) external; + function withdraw(address recipient, IERC20 token, uint256 amountShares) external; /** * @notice Used to convert a number of shares to the equivalent amount of underlying tokens for this strategy. @@ -41,9 +37,7 @@ interface IStrategy { * @return The amount of underlying tokens corresponding to the input `amountShares` * @dev Implementation for these functions in particular may vary significantly for different strategies */ - function sharesToUnderlying( - uint256 amountShares - ) external returns (uint256); + function sharesToUnderlying(uint256 amountShares) external returns (uint256); /** * @notice Used to convert an amount of underlying tokens to the equivalent amount of shares in this strategy. @@ -52,9 +46,7 @@ interface IStrategy { * @return The amount of underlying tokens corresponding to the input `amountShares` * @dev Implementation for these functions in particular may vary significantly for different strategies */ - function underlyingToShares( - uint256 amountUnderlying - ) external returns (uint256); + function underlyingToShares(uint256 amountUnderlying) external returns (uint256); /** * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in @@ -75,9 +67,7 @@ interface IStrategy { * @return The amount of shares corresponding to the input `amountUnderlying` * @dev Implementation for these functions in particular may vary significantly for different strategies */ - function sharesToUnderlyingView( - uint256 amountShares - ) external view returns (uint256); + function sharesToUnderlyingView(uint256 amountShares) external view returns (uint256); /** * @notice Used to convert an amount of underlying tokens to the equivalent amount of shares in this strategy. @@ -86,9 +76,7 @@ interface IStrategy { * @return The amount of shares corresponding to the input `amountUnderlying` * @dev Implementation for these functions in particular may vary significantly for different strategies */ - function underlyingToSharesView( - uint256 amountUnderlying - ) external view returns (uint256); + function underlyingToSharesView(uint256 amountUnderlying) external view returns (uint256); /** * @notice convenience function for fetching the current underlying value of all of the `user`'s shares in