Skip to content

Commit

Permalink
Merge pull request #3 from yearn/tests
Browse files Browse the repository at this point in the history
test: l1 escrow
  • Loading branch information
Schlagonia authored Apr 23, 2024
2 parents ef3cd38 + 56c77e0 commit afff1f9
Show file tree
Hide file tree
Showing 13 changed files with 581 additions and 191 deletions.
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
Expand Up @@ -10,6 +10,10 @@ import {IPolygonZkEVMBridge} from "./interfaces/Polygon/IPolygonZkEVMBridge.sol"
* @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");
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 @@ contract L1Deployer is DeployerBase, RoleManager {
}

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

IPolygonRollupManager public immutable rollupManager;
Expand Down Expand Up @@ -137,10 +132,10 @@ contract L1Deployer is DeployerBase, RoleManager {
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 @@ contract L1Deployer is DeployerBase, RoleManager {

// 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 @@ contract L1Deployer is DeployerBase, RoleManager {
}

/*//////////////////////////////////////////////////////////////
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 @@ contract L1Deployer is DeployerBase, RoleManager {
)
);

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

0 comments on commit afff1f9

Please sign in to comment.