Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L2 Minor changes #83

Merged
merged 4 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -56,5 +56,6 @@ jobs:
with:
check_hidden: true
check_filenames: true
ignore_words_list: amountIn
skip: package-lock.json,*.pdf,./.git

2 changes: 1 addition & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ optimizer = true
optimizer_runs = 200
evm_version = "cancun" # is live on mainnet
seed = "0x1337"
solc = "0.8.24"
solc = "0.8.26"
# via_ir = true

[fmt]
Expand Down
48 changes: 26 additions & 22 deletions script/DeployL2XPufETH.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ pragma solidity >=0.8.0 <0.9.0;
import "forge-std/Script.sol";
import { stdJson } from "forge-std/StdJson.sol";
import { BaseScript } from ".//BaseScript.s.sol";
import { XERC20PufferVault } from "../src/l2/XERC20PufferVault.sol";
import { UUPSUpgradeable } from "@openzeppelin-contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import { xPufETH } from "../src/l2/xPufETH.sol";
import { Initializable } from "openzeppelin/proxy/utils/Initializable.sol";
import { Timelock } from "../src/Timelock.sol";
import { ERC1967Proxy } from "openzeppelin/proxy/ERC1967/ERC1967Proxy.sol";
Expand Down Expand Up @@ -33,9 +32,9 @@ contract DeployL2XPufETH is BaseScript {
address pauserMultisig = vm.envOr("PAUSER_MULTISIG", makeAddr("pauserMultisig"));
address communityMultisig = vm.envOr("COMMUNITY_MULTISIG", makeAddr("communityMultisig"));

address _CONNEXT = 0x8247ed6d0a344eeae4edBC7e44572F1B70ECA82A; // change for mainnet
uint256 _MINTING_LIMIT = 1000 * 1e18;
uint256 _BURNING_LIMIT = 1000 * 1e18;
address _CONNEXT = 0x8247ed6d0a344eeae4edBC7e44572F1B70ECA82A; //@todo change for mainnet
uint256 _MINTING_LIMIT = 1000 * 1e18; //@todo
uint256 _BURNING_LIMIT = 1000 * 1e18; //@todo

function run() public broadcast {
AccessManager accessManager = new AccessManager(_broadcaster);
Expand All @@ -54,40 +53,45 @@ contract DeployL2XPufETH is BaseScript {
initialDelay: 7 days
});

console.log("AccessManager", address(timelock));
console.log("Timelock", address(timelock));

XERC20PufferVault newImplementation = new XERC20PufferVault();
console.log("XERC20PufferVault", address(newImplementation));
xPufETH newImplementation = new xPufETH();
console.log("XERC20PufferVaultImplementation", address(newImplementation));

bytes32 xPufETHSalt = bytes32("xPufETH");

ERC1967Proxy xPufETH = new ERC1967Proxy{ salt: xPufETHSalt }(
address(newImplementation), abi.encodeCall(XERC20PufferVault.initialize, (address(accessManager)))
);
console.log("xPufETHProxy", address(xPufETH));

vm.expectEmit(true, true, true, true);
emit Initializable.Initialized(1);
ERC1967Proxy xPufETHProxy = new ERC1967Proxy{ salt: xPufETHSalt }(
address(newImplementation), abi.encodeCall(xPufETH.initialize, (address(accessManager)))
);
console.log("xPufETHProxy", address(xPufETHProxy));

bytes memory data = abi.encodeWithSelector(xPufETH.setLimits.selector, _CONNEXT, _MINTING_LIMIT, _BURNING_LIMIT);

bytes memory data =
abi.encodeWithSelector(XERC20PufferVault.setLimits.selector, _CONNEXT, _MINTING_LIMIT, _BURNING_LIMIT);
accessManager.execute(address(xPufETHProxy), data);

accessManager.execute(address(xPufETH), data);
bytes4[] memory daoSelectors = new bytes4[](2);
daoSelectors[0] = xPufETH.setLockbox.selector;
daoSelectors[1] = xPufETH.setLimits.selector;

bytes4[] memory selectors = new bytes4[](2);
selectors[0] = XERC20PufferVault.setLockbox.selector;
selectors[1] = XERC20PufferVault.setLimits.selector;
bytes4[] memory publicSelectors = new bytes4[](2);
publicSelectors[0] = xPufETH.mint.selector;
publicSelectors[1] = xPufETH.burn.selector;

// Setup Access
accessManager.setTargetFunctionRole(address(xPufETH), selectors, ROLE_ID_DAO);
// Public selectors
accessManager.setTargetFunctionRole(address(xPufETHProxy), publicSelectors, accessManager.PUBLIC_ROLE());
// Dao selectors
accessManager.setTargetFunctionRole(address(xPufETHProxy), daoSelectors, ROLE_ID_DAO);

accessManager.grantRole(accessManager.ADMIN_ROLE(), address(timelock), 0);

// replace with dao and ops multisigs for mainnet
//@todo replace with dao and ops multisigs for mainnet
accessManager.grantRole(ROLE_ID_DAO, _broadcaster, 0);
accessManager.grantRole(ROLE_ID_OPERATIONS_MULTISIG, _broadcaster, 0);

// revoke on mainnet
//@todo revoke on mainnet
// accessManager.revokeRole(accessManager.ADMIN_ROLE(), _broadcaster);
}
}
5 changes: 4 additions & 1 deletion script/Roles.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ uint64 constant ROLE_ID_UPGRADER = 1;
// Role assigned to Operations Multisig
uint64 constant ROLE_ID_OPERATIONS_MULTISIG = 22;
uint64 constant ROLE_ID_OPERATIONS_PAYMASTER = 23;
uint64 constant ROLE_ID_OPERATIONS_COORDINATOR= 24;
uint64 constant ROLE_ID_OPERATIONS_COORDINATOR = 24;

// Role assigned to the Puffer Protocol
uint64 constant ROLE_ID_PUFFER_PROTOCOL = 1234;
Expand All @@ -24,3 +24,6 @@ uint64 constant ADMIN_ROLE = 0;

// Allowlister role for AVSContractsRegistry
uint64 constant ROLE_ID_AVS_COORDINATOR_ALLOWLISTER = 5;

// Lockbox role for ETH Mainnet
uint64 constant ROLE_ID_LOCKBOX = 7;
119 changes: 119 additions & 0 deletions src/XERC20Lockbox.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.4 <0.9.0;

import { IXERC20 } from "./interface/IXERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { SafeCast } from "@openzeppelin/contracts/utils/math/SafeCast.sol";
import { IXERC20Lockbox } from "./interface/IXERC20Lockbox.sol";

contract XERC20Lockbox is IXERC20Lockbox {
using SafeERC20 for IERC20;
using SafeCast for uint256;

/**
* @notice The XERC20 token of this contract
*/
IXERC20 public immutable XERC20;

/**
* @notice The ERC20 token of this contract
*/
IERC20 public immutable ERC20;

/**
* @notice Constructor
*
* @param xerc20 The address of the XERC20 contract
* @param erc20 The address of the ERC20 contract
*/
constructor(address xerc20, address erc20) {
XERC20 = IXERC20(xerc20);
ERC20 = IERC20(erc20);
}

/**
* @notice Deposit ERC20 tokens into the lockbox
*
* @param amount The amount of tokens to deposit
*/
function deposit(uint256 amount) external {
_deposit(msg.sender, amount);
}

/**
* @notice Deposit ERC20 tokens into the lockbox, and send the XERC20 to a user
*
* @param to The user to send the XERC20 to
* @param amount The amount of tokens to deposit
*/
function depositTo(address to, uint256 amount) external {
_deposit(to, amount);
}

/**
* @notice Not a native asset
*/
function depositNativeTo(address) public payable {
revert IXERC20Lockbox_NotNative();
}

/**
* @notice Deposit native tokens into the lockbox
*/
function depositNative() public payable {
revert IXERC20Lockbox_NotNative();
}

/**
* @notice Withdraw ERC20 tokens from the lockbox
*
* @param amount The amount of tokens to withdraw
*/
function withdraw(uint256 amount) external {
_withdraw(msg.sender, amount);
}

/**
* @notice Withdraw tokens from the lockbox
*
* @param to The user to withdraw to
* @param amount The amount of tokens to withdraw
*/
function withdrawTo(address to, uint256 amount) external {
_withdraw(to, amount);
}

/**
* @notice Withdraw tokens from the lockbox
*
* @param to The user to withdraw to
* @param amount The amount of tokens to withdraw
*/
function _withdraw(address to, uint256 amount) internal {
emit Withdraw(to, amount);

XERC20.burn(msg.sender, amount);
ERC20.safeTransfer(to, amount);
}

/**
* @notice Deposit tokens into the lockbox
*
* @param to The address to send the XERC20 to
* @param amount The amount of tokens to deposit
*/
function _deposit(address to, uint256 amount) internal {
ERC20.safeTransferFrom(msg.sender, address(this), amount);
XERC20.mint(to, amount);

emit Deposit(to, amount);
}

/**
* @notice Fallback function to deposit native tokens
*/
receive() external payable {
depositNative();
}
}
60 changes: 30 additions & 30 deletions src/l2/interface/IXERC20.sol → src/interface/IXERC20.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,18 @@ interface IXERC20 {
/**
* @notice Emits when a lockbox is set
*
* @param _lockbox The address of the lockbox
* @param lockbox The address of the lockbox
*/
event LockboxSet(address _lockbox);
event LockboxSet(address lockbox);

/**
* @notice Emits when a limit is set
*
* @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 limit too
* @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 limit too
*/
event BridgeLimitsSet(uint256 _mintingLimit, uint256 _burningLimit, address indexed _bridge);
event BridgeLimitsSet(uint256 mintingLimit, uint256 burningLimit, address indexed bridge);

/**
* @notice Reverts when a user with too low of a limit tries to call mint/burn
Expand Down Expand Up @@ -62,64 +62,64 @@ interface IXERC20 {
/**
* @notice Sets the lockbox address
*
* @param _lockbox The address of the lockbox
* @param lockbox The address of the lockbox
*/
function setLockbox(address _lockbox) external;
function setLockbox(address lockbox) 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
* @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 setLimits(address bridge, uint256 mintingLimit, uint256 burningLimit) external;

/**
* @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
* @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
*
* @param _bridge the bridge we are viewing the limits of
* @return _limit The limit the bridge has
* @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);

/**
* @notice Returns the current limit of a minter
*
* @param _minter The minter we are viewing the limits of
* @return _limit The limit the minter has
* @param minter The minter we are viewing the limits of
* @return limit The limit the minter has
*/
function mintingCurrentLimitOf(address _minter) external view returns (uint256 _limit);
function mintingCurrentLimitOf(address minter) 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
* @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 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
* @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;
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
* @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;
function burn(address user, uint256 amount) external;
}
Loading
Loading