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

test: l1 escrow #3

Merged
merged 4 commits into from
Apr 23, 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
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
"solhint-plugin-prettier": "^0.0.5"
},
"scripts": {
"format": "prettier --write 'src/**/*.(sol|json)'",
"format:check": "prettier --check 'src/**/*.*(sol|json)'",
"format": "prettier --write 'src/**/*.(sol|json)' 'test/**/*.(sol|json)'",
"format:check": "prettier --check 'src/**/*.*(sol|json)' 'test/**/*.(sol|json)'",
"lint": "solhint 'src/**/*.sol'",
"lint:fix": "solhint --fix 'src/**/*.sol'"
}
Expand Down
4 changes: 4 additions & 0 deletions src/DeployerBase.sol
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.20;

Check warning on line 2 in src/DeployerBase.sol

View workflow job for this annotation

GitHub Actions / solidity

Compiler version ^0.8.20 does not satisfy the 0.8.18 semver requirement

import {Proxy} from "@zkevm-stb/Proxy.sol";
import {ICREATE3Factory} from "./interfaces/ICREATE3Factory.sol";
Expand All @@ -10,20 +10,24 @@
* @notice To be inherited by the L1 and L2 Deployer's for common functionality.
*/
abstract contract DeployerBase {
/*//////////////////////////////////////////////////////////////
POSITION ID'S
//////////////////////////////////////////////////////////////*/

bytes32 public constant ESCROW_IMPLEMENTATION =
keccak256("Escrow Implementation");
bytes32 public constant L1_DEPLOYER = keccak256("L1 Deployer");
bytes32 public constant L2_DEPLOYER = keccak256("L2 Deployer");

/// @notice Address of the ICREATE3Factory contract used for deployment
ICREATE3Factory internal constant create3Factory =

Check warning on line 23 in src/DeployerBase.sol

View workflow job for this annotation

GitHub Actions / solidity

Constant name must be in capitalized SNAKE_CASE
ICREATE3Factory(0x93FEC2C00BfE902F733B57c5a6CeeD7CD1384AE1);

/// @notice Immutable original chain ID
uint256 public immutable originalChainID;

Check warning on line 27 in src/DeployerBase.sol

View workflow job for this annotation

GitHub Actions / solidity

Immutable variables name are set to be in capitalized SNAKE_CASE

/// @notice Address of the PolygonZkEVMBridge contract
IPolygonZkEVMBridge public immutable polygonZkEVMBridge;

Check warning on line 30 in src/DeployerBase.sol

View workflow job for this annotation

GitHub Actions / solidity

Immutable variables name are set to be in capitalized SNAKE_CASE

constructor(address _polygonZkEVMBridge) {
polygonZkEVMBridge = IPolygonZkEVMBridge(_polygonZkEVMBridge);
Expand Down
90 changes: 17 additions & 73 deletions src/L1Deployer.sol
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.20;

Check warning on line 2 in src/L1Deployer.sol

View workflow job for this annotation

GitHub Actions / solidity

Compiler version ^0.8.20 does not satisfy the 0.8.18 semver requirement

import {L1YearnEscrow} from "./L1YearnEscrow.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";

import {IPolygonRollupManager, IPolygonRollupContract} from "./interfaces/Polygon/IPolygonRollupManager.sol";

import {Proxy} from "@zkevm-stb/Proxy.sol";

import {RoleManager} from "./RoleManager.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

import {DeployerBase} from "./DeployerBase.sol";
import {L1YearnEscrow} from "./L1YearnEscrow.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {IPolygonRollupManager, IPolygonRollupContract} from "./interfaces/Polygon/IPolygonRollupManager.sol";

// TODO:
// getters for custom position holders
Expand Down Expand Up @@ -56,7 +51,7 @@
}

/*//////////////////////////////////////////////////////////////
POSITION ID'S
IMMUTABLE'S
//////////////////////////////////////////////////////////////*/

IPolygonRollupManager public immutable rollupManager;
Expand Down Expand Up @@ -137,10 +132,10 @@
ESCROW CREATION
//////////////////////////////////////////////////////////////*/

function newAsset(
function newEscrow(
uint32 _rollupID,
address _asset
) external virtual returns (address _vault, address _l1Escrow) {
) external virtual returns (address _l1Escrow, address _vault) {
// Verify the rollup Id is valid.
require(
address(chainConfig[_rollupID].rollupContract) != address(0),
Expand All @@ -156,61 +151,31 @@

// If not, deploy one and do full setup
if (_vault == address(0)) {
_vault = _deployDefaultVault(_asset);
_vault = _newVault(DEFAULT_ID, _asset);
}

// Deploy L1 Escrow.
_l1Escrow = _deployL1Escrow(_rollupID, _asset, _vault);
}

function newCustomAsset(
function newCustomVault(
uint32 _rollupID,
address _asset
) external virtual onlyRollupAdmin(_rollupID) returns (address _vault) {
string memory _rollupIDString = Strings.toString(_rollupID);

// Name is "{SYMBOL}-STB-{rollupID} yVault"
string memory _name = string(
abi.encodePacked(
ERC20(_asset).symbol(),
"-STB-",
_rollupIDString,
" yVault"
)
);
// Symbol is "stb{SYMBOL}-{rollupID}".
string memory _symbol = string(
abi.encodePacked(
"stb",
ERC20(_asset).symbol(),
"-",
_rollupIDString
)
);

_vault = _newVault(
_asset,
_name,
_symbol,
_rollupID,
2 ** 256 - 1,
defaultProfitMaxUnlock
);

// Custom Roles???
_newCustomAsset(_rollupID, _asset, _vault);
_vault = _newVault(_rollupID, _asset);
_newCustomVault(_rollupID, _asset, _vault);
}

function newCustomAsset(
function newCustomVault(
uint32 _rollupID,
address _asset,
address _vault
) external virtual onlyRollupAdmin(_rollupID) {
_addNewVault(_rollupID, _vault);
_newCustomAsset(_rollupID, _asset, _vault);
_newCustomVault(_rollupID, _asset, _vault);
}

function _newCustomAsset(
function _newCustomVault(
uint32 _rollupID,
address _asset,
address _vault
Expand All @@ -225,32 +190,9 @@
}

/*//////////////////////////////////////////////////////////////
VAULT CREATION
ESCROW CREATION
//////////////////////////////////////////////////////////////*/

function _deployDefaultVault(
address _asset
) internal virtual returns (address) {
// Name is "{SYMBOL}-STB yVault"
string memory _name = string(
abi.encodePacked(ERC20(_asset).symbol(), "-STB yVault")
);
// Symbol is "stb{SYMBOL}".
string memory _symbol = string(
abi.encodePacked("stb", ERC20(_asset).symbol())
);

return
_newVault(
_asset,
_name,
_symbol,
DEFAULT_ID,
2 ** 256 - 1,
defaultProfitMaxUnlock
);
}

function _deployL1Escrow(
uint32 _rollupID,
address _asset,
Expand All @@ -272,14 +214,16 @@
)
);

address expectedL1Escrow = getL1EscrowAddress(_asset);

_l1Escrow = _create3Deploy(
keccak256(abi.encodePacked(bytes("L1Escrow:"), _asset)),
getPositionHolder(ESCROW_IMPLEMENTATION),
data
);

// Make sure we got the right address.
require(_l1Escrow == getL1EscrowAddress(_asset), "wrong address");
require(_l1Escrow == expectedL1Escrow, "wrong address");

// Set the mapping
_chainConfig.escrows[_asset] = _l1Escrow;
Expand Down
43 changes: 38 additions & 5 deletions src/L1YearnEscrow.sol
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.20;

import {L1Escrow} from "@zkevm-stb/L1Escrow.sol";
import {IVault} from "@yearn-vaults/interfaces/IVault.sol";
import {L1Escrow, SafeERC20, IERC20} from "@zkevm-stb/L1Escrow.sol";

// ADD buffer
/**
* @title L1YearnEscrow
* @author yearn.fi
* @dev L1 escrow that will deploy the assets to a Yearn vault to earn yield.
*/
contract L1YearnEscrow is L1Escrow {
// ****************************
// * Libraries *
// ****************************

using SafeERC20 for IERC20;

// ****************************
// * Events *
// **************************
Expand Down Expand Up @@ -87,7 +97,9 @@ contract L1YearnEscrow is L1Escrow {
);

VaultStorage storage $ = _getVaultStorage();
// Set the vault variables
// Max approve the vault
originTokenAddress().forceApprove(_vaultAddress, 2 ** 256 - 1);
// Set the vault variable
$.vaultAddress = IVault(_vaultAddress);
}

Expand Down Expand Up @@ -131,23 +143,28 @@ contract L1YearnEscrow is L1Escrow {
address destinationAddress,
uint256 amount
) internal virtual override whenNotPaused {
// Withdraw from vault to receiver.
VaultStorage storage $ = _getVaultStorage();

// Check if there is enough loose balance.
uint256 underlyingBalance = originTokenAddress().balanceOf(
address(this)
);
if (underlyingBalance != 0) {
if (underlyingBalance >= amount) {
super._transferTokens(destinationAddress, amount);
return;
} else {
}

uint256 maxWithdraw = $.vaultAddress.maxWithdraw(address(this));
if (maxWithdraw < amount) {
super._transferTokens(destinationAddress, underlyingBalance);
unchecked {
amount = amount - underlyingBalance;
}
}
}

// Withdraw from vault to receiver.
$.vaultAddress.withdraw(amount, destinationAddress, address(this));
}

Expand Down Expand Up @@ -186,12 +203,28 @@ contract L1YearnEscrow is L1Escrow {
IVault oldVault = $.vaultAddress;
// If re-initializing to a new vault address.
if (address(oldVault) != address(0)) {
// Lower allowance to 0
originTokenAddress().forceApprove(address(oldVault), 0);

uint256 balance = oldVault.balanceOf(address(this));
// Withdraw the full balance of the current vault.
if (balance != 0) {
oldVault.redeem(balance, address(this), address(this));
}
}

// Migrate to new vault if applicable
if (_vaultAddress != address(0)) {
// Max approve the new vault
originTokenAddress().forceApprove(_vaultAddress, 2 ** 256 - 1);

// Deposit any loose funds
uint256 balance = originTokenAddress().balanceOf(address(this));
if (balance != 0)
IVault(_vaultAddress).deposit(balance, address(this));
}

// Update Storage
$.vaultAddress = IVault(_vaultAddress);

emit UpdateVaultAddress(_vaultAddress);
Expand Down
6 changes: 2 additions & 4 deletions src/L2Deployer.sol
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity ^0.8.20;

import {L2Escrow} from "@zkevm-stb/L2Escrow.sol";
import {L2Token} from "@zkevm-stb/L2Token.sol";
import {DeployerBase} from "./DeployerBase.sol";
import {L2Escrow} from "@zkevm-stb/L2Escrow.sol";
import {L2TokenConverter} from "@zkevm-stb/L2TokenConverter.sol";

import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

import {DeployerBase} from "./DeployerBase.sol";

// Array of tokens?
// m
contract L2Deployer is DeployerBase {
Expand Down
32 changes: 20 additions & 12 deletions src/RoleManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {Roles} from "@yearn-vaults/interfaces/Roles.sol";
import {IVault} from "@yearn-vaults/interfaces/IVault.sol";
import {IAccountant} from "./interfaces/Yearn/IAccountant.sol";
import {Registry} from "@vault-periphery/registry/Registry.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {ERC20} from "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import {DebtAllocatorFactory} from "@vault-periphery/debtAllocators/DebtAllocatorFactory.sol";

Expand Down Expand Up @@ -178,26 +179,34 @@ contract RoleManager {

/**
* @notice Creates a new endorsed vault.
* @param _rollupID Id of the rollup to deploy for.
* @param _asset Address of the underlying asset.
* @param _depositLimit The deposit limit to start the vault with.
* @param _profitMaxUnlockTime Time until profits are fully unlocked.
* @return _vault Address of the newly created vault.
*/
function _newVault(
address _asset,
string memory _name,
string memory _symbol,
uint32 _rollupID,
uint256 _depositLimit,
uint256 _profitMaxUnlockTime
address _asset
) internal virtual returns (address _vault) {
// Append the rollup ID for the name and symbol of custom vaults.
string memory _id = _rollupID == DEFAULT_ID
? ""
: string(abi.encodePacked("-", Strings.toString(_rollupID)));
// Name is "{SYMBOL}-STB yVault"
string memory _name = string(
abi.encodePacked(ERC20(_asset).symbol(), "-STB", _id, " yVault")
);
// Symbol is "stb{SYMBOL}".
string memory _symbol = string(
abi.encodePacked("stb", ERC20(_asset).symbol(), _id)
);

// Deploy through the registry so it is automatically endorsed.
_vault = Registry(getPositionHolder(REGISTRY)).newEndorsedVault(
_asset,
_name,
_symbol,
address(this),
_profitMaxUnlockTime
defaultProfitMaxUnlock
);

// Deploy a new debt allocator for the vault.
Expand All @@ -209,9 +218,8 @@ contract RoleManager {
// Set up the accountant.
_setAccountant(_vault);

if (_depositLimit != 0) {
_setDepositLimit(_vault, _depositLimit);
}
// Set deposit limit to max uint.
_setDepositLimit(_vault, 2 ** 256 - 1);

// Add the vault config to the mapping.
vaultConfig[_vault] = VaultConfig({
Expand Down Expand Up @@ -624,7 +632,7 @@ contract RoleManager {
* @return The default vault for the specified `_asset`.
*/
function getVault(address _asset) public view virtual returns (address) {
return _assetToVault[_asset][DEFAULT_ID];
return getVault(_asset, DEFAULT_ID);
}

/**
Expand Down
2 changes: 2 additions & 0 deletions src/interfaces/Polygon/IPolygonZkEVMBridge.sol
Original file line number Diff line number Diff line change
Expand Up @@ -118,4 +118,6 @@ interface IPolygonZkEVMBridge {
function networkID() external returns (uint32);

function polygonRollupManager() external view returns (address);

function depositCount() external view returns (uint256);
}
Loading
Loading