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

Feat/script migration #2

Merged
merged 77 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from 20 commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
5a66f8c
feat: deployAgTokenSideChain script
0xtekgrinder May 3, 2024
e00d733
feat: DeployChain script
0xtekgrinder May 3, 2024
adc10d3
feat: deployTokenSideChain script
0xtekgrinder May 3, 2024
c8081c9
feat: remove BasicScript
0xtekgrinder May 3, 2024
52a6e85
chore: update fs_permissions in foundry.toml
0xtekgrinder May 3, 2024
2ea1e7a
refactor: rename angleImpl to agTokenImpl
0xtekgrinder May 3, 2024
53ca2e9
feat: deploy proxy with create2
0xtekgrinder May 3, 2024
151d543
feat: rename to new A naming
0xtekgrinder May 3, 2024
142b50d
chore: add optimizer in ci profile
0xtekgrinder May 3, 2024
f23df19
feat: hardcode symbol for ANGLE
0xtekgrinder May 3, 2024
c6cc599
feat: check expectedAddress before create2
0xtekgrinder May 3, 2024
738cdbc
refactor: rename script to deploy angle on sidechain
0xtekgrinder May 3, 2024
306f43c
feat: in case of a mock coreborrow, initialize contracts
0xtekgrinder May 3, 2024
f58f8cc
chore: update utils dependency
0xtekgrinder May 3, 2024
b1f2467
feat: immutable proxy first to deployer hen real implementation
0xtekgrinder May 3, 2024
8f6dd98
feat: env vvariable for governor / guardian
0xtekgrinder May 3, 2024
8d1f5b8
feat: remove guardian proxyAdmin from DeployCHain script
0xtekgrinder May 6, 2024
b16fae4
feat: store addresses in a json
0xtekgrinder May 6, 2024
186b8a3
feat: LayerZeroBridgeTokenERC20
0xtekgrinder May 6, 2024
22d4eeb
feat: remove mock governor when using scripts as mock
0xtekgrinder May 6, 2024
bf8632b
feat: treasury write to addresses json
0xtekgrinder May 6, 2024
415acc1
feat: add back require to check preocmputed address
0xtekgrinder May 6, 2024
7dccd5d
feat: vanity now loads everything from multiple files
0xtekgrinder May 6, 2024
1bae1a4
feat: create2 deploy for veANGLE
0xtekgrinder May 6, 2024
ec8b092
fix: vanity address script returns salt
0xtekgrinder May 6, 2024
9825e75
feat: expected address is env or chain to contract on mainnet
0xtekgrinder May 6, 2024
3462276
chore: remove via_ir in foundry.toml
0xtekgrinder May 6, 2024
ecc5c3c
chore: update forge-std to add envExists
0xtekgrinder May 6, 2024
a2d5090
feat: ir-minmum in coverage
0xtekgrinder May 6, 2024
9b20ce3
chore: remappings for slither
0xtekgrinder May 6, 2024
668096e
chore: add back foundry compile before
0xtekgrinder May 6, 2024
4b6fe6e
chore: ignore script and test for slither
0xtekgrinder May 6, 2024
d676a98
chore: specify version for slither in ci
0xtekgrinder May 6, 2024
863f130
chore: remove wrong src
0xtekgrinder May 6, 2024
956c163
chore: tmate
0xtekgrinder May 7, 2024
73d5e3d
chore: try to run slither manually
0xtekgrinder May 7, 2024
9ad11f4
chore: set sarif file
0xtekgrinder May 7, 2024
b3389ab
chore: debug ci
0xtekgrinder May 7, 2024
2cffd77
chore: use new version of slither ci
0xtekgrinder May 7, 2024
774babc
feat: scripts works even if addresses.json doesn't exists
0xtekgrinder May 10, 2024
56705bc
chore: update utils dependency
0xtekgrinder May 10, 2024
0be6d7d
fix: compile DeployAgTokenSideChain
0xtekgrinder May 10, 2024
d2943e4
chore: manual ci for slither
0xtekgrinder May 10, 2024
5afd516
chore: try to set output to a constant
0xtekgrinder May 10, 2024
7e34871
chore: try to rename sarif file
0xtekgrinder May 10, 2024
81db0ac
chore: add an && in stead of | in ci
0xtekgrinder May 10, 2024
3feb86e
chore: try to redirect output to stdout
0xtekgrinder May 10, 2024
34814e5
chore: results.sarif file
0xtekgrinder May 10, 2024
a735cbd
chore: upgrade utils dependency
0xtekgrinder May 13, 2024
bef4961
feat: change governor optional
0xtekgrinder May 16, 2024
7a14f59
feat: governor and guardian inside addresses.json
0xtekgrinder May 16, 2024
e728a7f
chore: loads slither errors
0xtekgrinder May 16, 2024
b78e9f8
chore: update utils dependency
0xtekgrinder May 17, 2024
9b25567
feat: update vanity of EURA
0xtekgrinder May 17, 2024
66ecf40
feat: new salt for EUR
0xtekgrinder May 17, 2024
e0c6ab9
chore: update foundry.toml to add base and linea etherscan api keys
0xtekgrinder May 17, 2024
488d8ab
feat: expected addresses for EURA and ANGLE
0xtekgrinder May 17, 2024
207b31c
chore: remove base from etherscan keys
0xtekgrinder May 17, 2024
3c031a7
feat: mantle
0xtekgrinder May 17, 2024
d32b217
feat: update name of AngleSideChain to ANGLE
0xtekgrinder Jun 10, 2024
e4e830e
feat: setuseCustomAdapterParams
0xtekgrinder Jun 11, 2024
b8fde5d
feat: useCustomAdapaters good interface
0xtekgrinder Jun 11, 2024
4b83dcc
feat: all steps to deploy a new chain
0xtekgrinder Jun 13, 2024
1769fc4
feat: transfer ownership of ProxyAdmin
0xtekgrinder Jun 13, 2024
3158f48
feat: add governor when deploying a new chain
0xtekgrinder Jun 13, 2024
fe188ad
feat: remove useless line
0xtekgrinder Jun 13, 2024
fcf0901
feat: finalize is optional
0xtekgrinder Jun 13, 2024
055c586
feat: deploy savings
0xtekgrinder Jun 14, 2024
29fe50b
fix: savings now compile
0xtekgrinder Jun 14, 2024
0c1a784
feat: change address for savings to arbitrum
0xtekgrinder Jun 14, 2024
50da920
fix: correct epxectedAddress
0xtekgrinder Jun 14, 2024
8504eb2
fix: write savings address in json
0xtekgrinder Jun 14, 2024
7eceaaf
feat: deduce stableType from STABLE_NAME
0xtekgrinder Jun 17, 2024
493d430
feat: add blast config
0xtekgrinder Jun 18, 2024
212423c
fix: forwardUtils
0xtekgrinder Jun 18, 2024
5f7275a
fix: deployChain works without sdk
0xtekgrinder Jun 24, 2024
e661aac
feat: governor and guardian addresses
0xtekgrinder Jun 24, 2024
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
150 changes: 150 additions & 0 deletions contracts/agToken/layerZero/LayerZeroBridgeTokenERC20.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
// SPDX-License-Identifier: GPL-3.0

pragma solidity ^0.8.12;

import "./utils/OFTCore.sol";
import "../../interfaces/IAgTokenSideChainMultiBridge.sol";
import "oz-upgradeable/security/PausableUpgradeable.sol";
import "oz-upgradeable/token/ERC20/ERC20Upgradeable.sol";

/// @title LayerZeroBridgeTokenERC20
/// @author Angle Core Team, forked from https://github.com/LayerZero-Labs/solidity-examples/blob/main/contracts/token/oft/OFT.sol

Check warning on line 11 in contracts/agToken/layerZero/LayerZeroBridgeTokenERC20.sol

View workflow job for this annotation

GitHub Actions / lint

Line length must be no more than 120 but current length is 130
/// @notice Contract to be deployed on a L2/sidechain for bridging a token (ANGLE for instance) using
/// a bridge intermediate token and LayerZero
contract LayerZeroBridgeTokenERC20 is OFTCore, ERC20Upgradeable, PausableUpgradeable {
/// @notice Address of the bridgeable token
IAgTokenSideChainMultiBridge public canonicalToken;

// =================================== ERRORS ==================================

error InvalidAllowance();

// ================================ CONSTRUCTOR ================================

/// @notice Initializes the contract
/// @param _name Name of the token corresponding to this contract
/// @param _symbol Symbol of the token corresponding to this contract
/// @param _lzEndpoint Layer zero endpoint to pass messages
/// @param _coreBorrow Address of the `CoreBorrow` contract used for access control
/// @param _canonicalToken Address of the bridgeable token
function initialize(
string memory _name,
string memory _symbol,
address _lzEndpoint,
address _coreBorrow,
address _canonicalToken
) external initializer {
if (_canonicalToken == address(0)) revert ZeroAddress();
__ERC20_init_unchained(_name, _symbol);
__LzAppUpgradeable_init(_lzEndpoint, _coreBorrow);

canonicalToken = IAgTokenSideChainMultiBridge(_canonicalToken);
_approve(address(this), _canonicalToken, type(uint256).max);
}

/// @custom:oz-upgrades-unsafe-allow constructor
constructor() initializer {}

// ===================== EXTERNAL PERMISSIONLESS FUNCTIONS =====================

/// @inheritdoc OFTCore
function sendWithPermit(
uint16 _dstChainId,
bytes memory _toAddress,
uint256 _amount,
address payable _refundAddress,
address _zroPaymentAddress,
bytes memory _adapterParams,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public payable override {
canonicalToken.permit(msg.sender, address(this), _amount, deadline, v, r, s);
send(_dstChainId, _toAddress, _amount, _refundAddress, _zroPaymentAddress, _adapterParams);
}

/// @inheritdoc OFTCore
function withdraw(uint256 amount, address recipient) external override returns (uint256 amountMinted) {
// Does not check allowances as transfers from `msg.sender`
_transfer(msg.sender, address(this), amount);
amountMinted = canonicalToken.swapIn(address(this), amount, recipient);
uint256 leftover = balanceOf(address(this));
if (leftover > 0) {
_transfer(address(this), msg.sender, leftover);
}
}

// ============================= INTERNAL FUNCTIONS ============================

/// @inheritdoc OFTCore
function _debitFrom(
uint16,
bytes memory,
uint256 _amount
) internal override whenNotPaused returns (uint256 amountSwapped) {
// No need to use safeTransferFrom as we know this implementation reverts on failure
canonicalToken.transferFrom(msg.sender, address(this), _amount);

// Swap canonical for this bridge token. There may be some fees
amountSwapped = canonicalToken.swapOut(address(this), _amount, address(this));
_burn(address(this), amountSwapped);
}
Fixed Show fixed Hide fixed

/// @inheritdoc OFTCore
function _debitCreditFrom(uint16, bytes memory, uint256 _amount) internal override whenNotPaused returns (uint256) {
_burn(msg.sender, _amount);
return _amount;
}

/// @inheritdoc OFTCore
function _creditTo(
uint16,
address _toAddress,
uint256 _amount
) internal override whenNotPaused returns (uint256 amountMinted) {
_mint(address(this), _amount);
amountMinted = canonicalToken.swapIn(address(this), _amount, _toAddress);
uint256 leftover = balanceOf(address(this));
if (leftover > 0) {
_transfer(address(this), _toAddress, leftover);
}
}

// =============================== VIEW FUNCTIONS ==============================

/// @inheritdoc ERC165Upgradeable
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return
interfaceId == type(IOFT).interfaceId ||
interfaceId == type(IERC20).interfaceId ||
super.supportsInterface(interfaceId);
}

// ============================ GOVERNANCE FUNCTIONS ===========================

/// @notice Mints the intermediate contract to the `canonicalToken`
/// @dev Used to increase the bridging capacity
function mint(uint256 amount) external onlyGovernorOrGuardian {
_mint(address(canonicalToken), amount);
}

/// @notice Burns the intermediate contract from the `canonicalToken`
/// @dev Used to decrease the bridging capacity
function burn(uint256 amount) external onlyGovernorOrGuardian {
_burn(address(canonicalToken), amount);
}

/// @notice Increases allowance of the `canonicalToken`
function setupAllowance() public onlyGovernorOrGuardian {
_approve(address(this), address(canonicalToken), type(uint256).max);
}

/// @notice Pauses bridging through the contract
/// @param pause Future pause status
function pauseSendTokens(bool pause) external onlyGovernorOrGuardian {
pause ? _pause() : _unpause();
}

uint256[49] private __gap;
Fixed Show fixed Hide fixed
}
Fixed Show fixed Hide fixed
Fixed Show fixed Hide fixed
2 changes: 2 additions & 0 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ optimizer = true
optimizer_runs = 1000
solc_version = "0.8.22"
ffi = true
fs_permissions = [{ access = "read-write", path = "./scripts/vanity.json"}, { access = "read-write", path = "./scripts/addresses.json"}]

[fuzz]
runs = 10000
Expand Down Expand Up @@ -60,6 +61,7 @@ depth = 1
fail_on_revert = false

[profile.ci]
optimizer = true
src = "test"
via_ir = false
gas_reports = ["*"]
Expand Down
2 changes: 1 addition & 1 deletion lib/utils
24 changes: 0 additions & 24 deletions scripts/BasicScript.s.sol

This file was deleted.

136 changes: 136 additions & 0 deletions scripts/DeployAgTokenSideChainMultiBridge.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.12;

import "forge-std/Script.sol";
import "./utils/Constants.s.sol";
import "utils/src/CommonUtils.sol";
import { AgTokenSideChainMultiBridge } from "contracts/agToken/AgTokenSideChainMultiBridge.sol";
import { LayerZeroBridgeToken } from "contracts/agToken/layerZero/LayerZeroBridgeToken.sol";
import { ICoreBorrow } from "contracts/interfaces/ICoreBorrow.sol";
import { Treasury } from "contracts/treasury/Treasury.sol";
import { ImmutableCreate2Factory } from "contracts/interfaces/external/create2/ImmutableCreate2Factory.sol";

contract DeployAgTokenSideChainMultiBridge is Script, CommonUtils {
using stdJson for string;

function run() external {
/** TODO complete */
string memory stableName = vm.envString("STABLE_NAME");
address expectedAddress = vm.envAddress("EXPECTED_ADDRESS");
uint256 totalLimit = vm.envUint("TOTAL_LIMIT");
uint256 hourlyLimit = vm.envUint("HOURLY_LIMIT");
uint256 chainTotalHourlyLimit = vm.envUint("CHAIN_TOTAL_HOURLY_LIMIT");
bool mock = vm.envOr("MOCK", false);
/** END complete */

uint256 deployerPrivateKey = vm.deriveKey(vm.envString("MNEMONIC_MAINNET"), "m/44'/60'/0'/0/", 0);
address deployer = vm.addr(deployerPrivateKey);
string memory jsonVanity = vm.readFile(JSON_VANITY_PATH);
bytes32 salt = bytes32(abi.encodePacked(deployer, abi.encodePacked(uint96(jsonVanity.readUint("$.init")))));
uint256 chainId = vm.envUint("CHAIN_ID");

string memory json = vm.readFile(JSON_ADDRESSES_PATH);
address proxyAdmin;
address coreBorrow;
if (vm.keyExistsJson(json, ".proxyAdmin")) {
proxyAdmin = vm.parseJsonAddress(json, ".proxyAdmin");
} else {
proxyAdmin = _chainToContract(chainId, ContractType.ProxyAdmin);
}
if (vm.keyExistsJson(json, ".coreBorrow")) {
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is the json per chain or something like this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the json so far is for all chains. In my mind we deploy one chain at a time so no real need for multiples

coreBorrow = vm.parseJsonAddress(json, ".coreBorrow");
} else {
coreBorrow = _chainToContract(chainId, ContractType.CoreBorrow);
}
ILayerZeroEndpoint lzEndpoint = _lzEndPoint(chainId);

vm.startBroadcast(deployerPrivateKey);

AgTokenSideChainMultiBridge agTokenImpl = new AgTokenSideChainMultiBridge();
console.log("AgTokenSideChainMultiBridge Implementation deployed at", address(agTokenImpl));

ImmutableCreate2Factory create2Factory = ImmutableCreate2Factory(IMMUTABLE_CREATE2_FACTORY_ADDRESS);
bytes memory initCode = abi.encodePacked(
0xtekgrinder marked this conversation as resolved.
Show resolved Hide resolved
type(TransparentUpgradeableProxy).creationCode,
abi.encode(IMMUTABLE_CREATE2_FACTORY_ADDRESS, deployer, "")
);
address computedAddress = create2Factory.findCreate2Address(salt, initCode);
console.log("AgTokenSideChainMultiBridge Proxy Supposed to deploy: %s", computedAddress);

// require(computedAddress == expectedAddress, "Computed address does not match expected address");
0xtekgrinder marked this conversation as resolved.
Show resolved Hide resolved

AgTokenSideChainMultiBridge agToken = AgTokenSideChainMultiBridge(create2Factory.safeCreate2(salt, initCode));
TransparentUpgradeableProxy(payable(address(agToken))).upgradeTo(address(agTokenImpl));
TransparentUpgradeableProxy(payable(address(agToken))).changeAdmin(proxyAdmin);
console.log("AgTokenSideChainMultiBridge Proxy deployed at", address(agToken));

Treasury treasuryImpl = new Treasury();
console.log("Treasury Implementation deployed at", address(treasuryImpl));

Treasury treasuryProxy = Treasury(
address(
_deployUpgradeable(
proxyAdmin,
address(treasuryImpl),
abi.encodeWithSelector(Treasury.initialize.selector, coreBorrow, address(agToken))
)
)
);
console.log("Treasury Proxy deployed at", address(treasuryProxy));

agToken.initialize(string.concat(stableName, "A"), string.concat(stableName, "A"), address(treasuryProxy));
0xtekgrinder marked this conversation as resolved.
Show resolved Hide resolved

LayerZeroBridgeToken lzImpl = new LayerZeroBridgeToken();
console.log("LayerZeroBridgeToken Implementation deployed at", address(lzImpl));
LayerZeroBridgeToken lzProxy = LayerZeroBridgeToken(
address(
_deployUpgradeable(
proxyAdmin,
address(lzImpl),
abi.encodeWithSelector(
LayerZeroBridgeToken.initialize.selector,
string.concat("LayerZero Bridge ", stableName, "A"),
string.concat("LZ-", stableName, "A"),
address(lzEndpoint),
address(treasuryProxy),
0
)
)
)
);
console.log("LayerZeroBridgeToken Proxy deployed at", address(lzProxy));

if (mock) {
agToken.addBridgeToken(address(lzProxy), totalLimit, hourlyLimit, 0, false);
agToken.setChainTotalHourlyLimit(chainTotalHourlyLimit);
LayerZeroBridgeToken(address(lzProxy)).setUseCustomAdapterParams(1);

(uint256[] memory chainIds, address[] memory contracts) = _getConnectedChains(stableName);

// Set trusted remote from current chain
for (uint256 i = 0; i < contracts.length; i++) {
if (chainIds[i] == chainId) {
continue;
}

lzProxy.setTrustedRemote(_getLZChainId(chainIds[i]), abi.encodePacked(contracts[i], address(lzProxy)));
}

// add real governor
address realGovernor = vm.envOr("REAL_GOVERNOR", _chainToContract(chainId, ContractType.GovernorMultisig));
coreBorrow.addGovernor(realGovernor);
coreBorrow.removeGovernor(deployer);
}

string memory json2 = "output";
string[] memory keys = vm.parseJsonKeys(json, "");
for (uint256 i = 0; i < keys.length; i++) {
json2.serialize(keys[i], json.readAddress(string.concat(".", keys[i])));
}
json2.serialize("agToken", address(agToken));
0xtekgrinder marked this conversation as resolved.
Show resolved Hide resolved
json2 = json2.serialize("lzAgToken", address(lzProxy));
json2.write(JSON_ADDRESSES_PATH);

vm.stopBroadcast();
}
}
Loading
Loading