Skip to content

Commit 637fb40

Browse files
committed
some scaffolding
1 parent 7fdf6e1 commit 637fb40

File tree

3 files changed

+246
-1
lines changed

3 files changed

+246
-1
lines changed
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
// SPDX-License-Identifier: BUSL-1.1
2+
pragma solidity ^0.8.0;
3+
4+
/**
5+
* @title OUSD Yearn V3 Master Strategy - the Mainnet part
6+
* @author Origin Protocol Inc
7+
*/
8+
9+
import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
10+
import { IERC20, InitializableAbstractStrategy } from "../../utils/InitializableAbstractStrategy.sol";
11+
12+
contract YearnV3MasterStrategy is InitializableAbstractStrategy {
13+
using SafeERC20 for IERC20;
14+
15+
/**
16+
* @param _stratConfig The platform and OToken vault addresses
17+
*/
18+
constructor(BaseStrategyConfig memory _stratConfig)
19+
InitializableAbstractStrategy(_stratConfig)
20+
{}
21+
22+
/**
23+
* Initializer for setting up strategy internal state.
24+
* @param _rewardTokenAddresses Addresses of reward tokens
25+
* @param _assets Addresses of supported assets
26+
* @param _pTokens Platform Token corresponding addresses
27+
*/
28+
function initialize(
29+
address[] calldata _rewardTokenAddresses,
30+
address[] calldata _assets,
31+
address[] calldata _pTokens
32+
) external onlyGovernor initializer {
33+
InitializableAbstractStrategy._initialize(
34+
_rewardTokenAddresses,
35+
_assets,
36+
_pTokens
37+
);
38+
}
39+
40+
/**
41+
* @dev Deposit asset into mainnet strategy making them ready to be
42+
* bridged to Slave part of the strategy
43+
* @param _asset Address of asset to deposit
44+
* @param _amount Amount of asset to deposit
45+
*/
46+
function deposit(address _asset, uint256 _amount)
47+
external
48+
override
49+
onlyVault
50+
nonReentrant
51+
{
52+
53+
emit Deposit(_asset, _asset, _amount);
54+
}
55+
56+
/**
57+
* @dev Bridge the assets prepared by a previous Deposit call to the
58+
* Slave part of the strategy
59+
* @param _amount Amount of asset to deposit
60+
* @param quote Quote to bridge the assets to the Slave part of the strategy
61+
*/
62+
function depositWithQuote(uint256 _amount, bytes calldata quote)
63+
external
64+
onlyGovernorOrStrategist
65+
nonReentrant
66+
{
67+
68+
// TODO: implement this
69+
}
70+
71+
/**
72+
* @dev Deposit the entire balance
73+
*/
74+
function depositAll() external override onlyVault nonReentrant {
75+
for (uint256 i = 0; i < assetsMapped.length; i++) {
76+
uint256 balance = IERC20(assetsMapped[i]).balanceOf(address(this));
77+
if (balance > 0) {
78+
emit Deposit(assetsMapped[i], assetsMapped[i], balance);
79+
}
80+
}
81+
}
82+
83+
/**
84+
* @dev Send a withdrawal Wormhole message requesting a certain withdrawal amount
85+
* @param _recipient Address to receive withdrawn asset
86+
* @param _asset Address of asset to withdraw
87+
* @param _amount Amount of asset to withdraw
88+
*/
89+
function withdraw(
90+
address _recipient,
91+
address _asset,
92+
uint256 _amount
93+
) external override onlyVault nonReentrant {
94+
require(_amount > 0, "Must withdraw something");
95+
require(_recipient == vaultAddress, "Only Vault can withdraw");
96+
97+
// Withdraw the funds from this strategy to the Vault once
98+
// they are allready bridged here
99+
}
100+
101+
/**
102+
* @dev Send a withdrawal Wormhole message requesting a certain withdrawal amount
103+
* @param _recipient Address to receive withdrawn asset
104+
* @param _asset Address of asset to withdraw
105+
* @param _amount Amount of asset to withdraw
106+
* @param quote Quote to bridge the assets to the Master part of the strategy
107+
*/
108+
function withdrawWithQuote(
109+
address _recipient,
110+
address _asset,
111+
uint256 _amount,
112+
bytes calldata quote
113+
) external onlyGovernorOrStrategist nonReentrant {
114+
require(_amount > 0, "Must withdraw something");
115+
require(_recipient == vaultAddress, "Only Vault can withdraw");
116+
}
117+
118+
/**
119+
* @dev Remove all assets from platform and send them to Vault contract.
120+
*/
121+
function withdrawAll() external override onlyVaultOrGovernor nonReentrant {
122+
//
123+
// TODO: implement this
124+
}
125+
126+
/**
127+
* @dev Get the total asset value held in the platform
128+
* @param _asset Address of the asset
129+
* @return balance Total value of the asset in the platform
130+
*/
131+
function checkBalance(address _asset)
132+
external
133+
view
134+
override
135+
returns (uint256 balance)
136+
{
137+
// USDC balance on this contract
138+
// + USDC being bridged
139+
// + USDC cached in the corresponding Slave part of this contract
140+
}
141+
142+
/**
143+
* @dev Returns bool indicating whether asset is supported by strategy
144+
* @param _asset Address of the asset
145+
*/
146+
function supportsAsset(address _asset) public view override returns (bool) {
147+
return assetToPToken[_asset] != address(0);
148+
}
149+
150+
/**
151+
* @dev Approve the spending of all assets
152+
*/
153+
function safeApproveAllTokens()
154+
external
155+
override
156+
onlyGovernor
157+
nonReentrant
158+
{
159+
160+
}
161+
162+
/**
163+
* @dev
164+
* @param _asset Address of the asset to approve
165+
* @param _aToken Address of the aToken
166+
*/
167+
// solhint-disable-next-line no-unused-vars
168+
function _abstractSetPToken(address _asset, address _aToken)
169+
internal
170+
override
171+
{
172+
}
173+
174+
/**
175+
* @dev
176+
*/
177+
function collectRewardTokens()
178+
external
179+
override
180+
onlyHarvester
181+
nonReentrant
182+
{
183+
184+
}
185+
}

contracts/deploy/deployActions.js

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@ const {
1717
isHoodi,
1818
isHoodiOrFork,
1919
} = require("../test/helpers.js");
20-
const { deployWithConfirmation, withConfirmation } = require("../utils/deploy");
20+
const { deployWithConfirmation, withConfirmation, encodeSaltForCreateX } = require("../utils/deploy");
2121
const { metapoolLPCRVPid } = require("../utils/constants");
2222
const { replaceContractAt } = require("../utils/hardhat");
2323
const { resolveContract } = require("../utils/resolvers");
2424
const { impersonateAccount, getSigner } = require("../utils/signers");
2525
const { getDefenderSigner } = require("../utils/signersNoHardhat");
2626
const { getTxOpts } = require("../utils/tx");
27+
const createxAbi = require("../abi/createx.json");
28+
2729
const {
2830
beaconChainGenesisTimeHoodi,
2931
beaconChainGenesisTimeMainnet,
@@ -1682,6 +1684,39 @@ const deploySonicSwapXAMOStrategyImplementation = async () => {
16821684
return cSonicSwapXAMOStrategy;
16831685
};
16841686

1687+
// deploys an instance of InitializeGovernedUpgradeabilityProxy where address is defined by salt
1688+
const deployProxyWithCreateX = async (salt) => {
1689+
const { deployerAddr } = await getNamedAccounts();
1690+
const sDeployer = await ethers.provider.getSigner(deployerAddr);
1691+
log(`Deploying proxy with salt: ${salt} as deployer ${deployerAddr}`);
1692+
1693+
const cCreateX = await ethers.getContractAt(createxAbi, addresses.createX);
1694+
const factoryEncodedSalt = encodeSaltForCreateX(deployerAddr, false, 1);
1695+
1696+
const getFactoryBytecode = async () => {
1697+
// No deployment needed—get factory directly from artifacts
1698+
const factory = await ethers.getContractFactory("InitializeGovernedUpgradeabilityProxy");
1699+
return factory.bytecode;
1700+
}
1701+
1702+
const txResponse = await withConfirmation(
1703+
cCreateX
1704+
.connect(sDeployer)
1705+
.deployCreate2(factoryEncodedSalt, getFactoryBytecode())
1706+
);
1707+
1708+
const contractCreationTopic =
1709+
"0xb8fda7e00c6b06a2b54e58521bc5894fee35f1090e5a3bb6390bfe2b98b497f7";
1710+
const txReceipt = await txResponse.wait();
1711+
const proxyAddress = ethers.utils.getAddress(
1712+
`0x${txReceipt.events
1713+
.find((event) => event.topics[0] === contractCreationTopic)
1714+
.topics[1].slice(26)}`
1715+
);
1716+
1717+
return proxyAddress;
1718+
};
1719+
16851720
module.exports = {
16861721
deployOracles,
16871722
deployCore,
@@ -1719,4 +1754,5 @@ module.exports = {
17191754
deployPlumeMockRoosterAMOStrategyImplementation,
17201755
getPlumeContracts,
17211756
deploySonicSwapXAMOStrategyImplementation,
1757+
deployProxyWithCreateX,
17221758
};
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
const { deploymentWithGovernanceProposal } = require("../../utils/deploy");
2+
const addresses = require("../../utils/addresses");
3+
const { deployProxyWithCreateX } = require("../deployActions");
4+
5+
module.exports = deploymentWithGovernanceProposal(
6+
{
7+
deployName: "159_yearn_strategy",
8+
forceDeploy: false,
9+
reduceQueueTime: true,
10+
deployerIsProposer: false,
11+
proposalId: "",
12+
},
13+
async ({ deployWithConfirmation }) => {
14+
// the salt needs to match the salt on the base chain deploying the other part of the strategy
15+
const salt = "Yean strategy 1";
16+
const proxyAddress = await deployProxyWithCreateX(salt);
17+
console.log(`Proxy address: ${proxyAddress}`);
18+
19+
20+
return {
21+
actions: [],
22+
};
23+
}
24+
);

0 commit comments

Comments
 (0)