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

add gnosis chain with sushiswap, curve, and swapr strategies #187

Open
wants to merge 15 commits into
base: master
Choose a base branch
from
Open
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,4 @@
"semi": "error"
}
}
}
}
17 changes: 10 additions & 7 deletions scripts/degenApe.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ const outputFolder = "scripts/degenApe/degenApeOutputs";
// by the script from the strategy address.
// @param - componentAddresses: The underlying token addresses of the lp. These will be added
const pfcoreArgs = {
chain: "optimism",
protocols: ["zipswap"],
chain: "gnosis",
protocols: ["swapr"],
extraTags: [],
liquidityURL: "https://zipswap.fi/#/add/",
rewardTokens: ["zip", "gohm"],
rewardTokens: ["swapr", "gno"],
jarCode: "1e",
farmAddress: "",
componentNames: [],
Expand All @@ -48,15 +48,18 @@ const pfcoreArgs = {
// Addresses & Contracts
const governance = "0x4204FDD868FFe0e62F57e6A626F8C9530F7d5AD1";
const strategist = "0x4204FDD868FFe0e62F57e6A626F8C9530F7d5AD1";
const controller = "0xc335740c951F45200b38C5Ca84F0A9663b51AEC6";
const controller = "0xe5E231De20C68AabB8D669f87971aE57E2AbF680";
const timelock = "0x4204FDD868FFe0e62F57e6A626F8C9530F7d5AD1";
const harvester = ["0x0f571D2625b503BB7C1d2b5655b483a2Fa696fEf"];

const contracts = [
"src/strategies/optimism/zipswap/strategy-zip-$gohm-$weth-lp.sol:StrategyZipEthGohmLp"
"src/strategies/gnosis/swapr/strategy-swapr-cow-weth-lp.sol:StrategySwaprCowWethLp",
"src/strategies/gnosis/swapr/strategy-swapr-cow-gno-lp.sol:StrategySwaprCowGnoLp"
];

const testedStrategies = [];
const testedStrategies = [
"0x1f84E30b463fE22FC26D1806149bE1e3E848Cfd9"
];

const executeTx = async (calls, fn, ...args) => {
let transaction;
Expand Down Expand Up @@ -238,7 +241,7 @@ ratio: ${ratio.toString()}
const main = async () => {
await deployContractsAndGeneratePfcore();
// await fastVerifyContracts(testedStrategies);
await slowVerifyContracts(testedStrategies);
await slowVerifyContracts(testedStrategies, governance, strategist, controller, timelock);
};

main()
Expand Down
2 changes: 1 addition & 1 deletion scripts/degenUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const fastVerifyContracts = async (strategies) => {
}

// Use this for verificationof 5 contracts or more
const slowVerifyContracts = async (strategies) => {
const slowVerifyContracts = async (strategies, governance, strategist, controller, timelock) => {
for (strategy of strategies) {
try {
await hre.run("verify:verify", {
Expand Down
6 changes: 4 additions & 2 deletions scripts/pfcoreUtils.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
const outputFolderSetup = async () => {
const fs = require("fs");

const outputFolderSetup = async (outputFolder, pfcoreArgs) => {
try {
if (!fs.existsSync(outputFolder)) {
fs.mkdirSync(outputFolder)
Expand Down Expand Up @@ -43,7 +45,7 @@ const incrementJar = async (jarCode, index) => {
}
};

const generateJarBehaviorDiscovery = async (args) => {
const generateJarBehaviorDiscovery = async (args, outputFolder) => {
const modelImport = `${args.protocols.map(x => x.toUpperCase()).join('_')}_${args.componentNames.map(x => x.toUpperCase()).join('_')};
`
const implImport = `import { ${args.protocols.map(x => x.slice(0, 1).toUpperCase().concat(x.slice(1))).join('').concat(args.componentNames.map(x => x.slice(0, 1).toUpperCase().concat(x.slice(1))).join(''))} } from './impl/${args.chain}-${args.protocols.join('-')}-${args.componentNames.join('-')}';
Expand Down
112 changes: 27 additions & 85 deletions src/controller-v4.sol
Original file line number Diff line number Diff line change
Expand Up @@ -90,10 +90,7 @@ contract ControllerV4 {
}

function setJar(address _token, address _jar) public {
require(
msg.sender == strategist || msg.sender == governance,
"!strategist"
);
require(msg.sender == strategist || msg.sender == governance, "!strategist");
require(jars[_token] == address(0), "jar");
jars[_token] = _jar;
}
Expand Down Expand Up @@ -125,14 +122,12 @@ contract ControllerV4 {
}

function setStrategy(address _token, address _strategy) public {
require(
msg.sender == strategist || msg.sender == governance,
"!strategist"
);
require(msg.sender == strategist || msg.sender == governance, "!strategist");
require(approvedStrategies[_token][_strategy] == true, "!approved");

address _current = strategies[_token];
if (_current != address(0)) {
uint256 _balance = IERC20(_token).balanceOf(_current);
if (_current != address(0) && _balance > 0) {
IStrategy(_current).withdrawAll();
}
strategies[_token] = _strategy;
Expand All @@ -157,28 +152,17 @@ contract ControllerV4 {
}

function withdrawAll(address _token) public {
require(
msg.sender == strategist || msg.sender == governance,
"!strategist"
);
require(msg.sender == strategist || msg.sender == governance, "!strategist");
IStrategy(strategies[_token]).withdrawAll();
}

function inCaseTokensGetStuck(address _token, uint256 _amount) public {
require(
msg.sender == strategist || msg.sender == governance,
"!governance"
);
require(msg.sender == strategist || msg.sender == governance, "!governance");
IERC20(_token).safeTransfer(msg.sender, _amount);
}

function inCaseStrategyTokenGetStuck(address _strategy, address _token)
public
{
require(
msg.sender == strategist || msg.sender == governance,
"!governance"
);
function inCaseStrategyTokenGetStuck(address _strategy, address _token) public {
require(msg.sender == strategist || msg.sender == governance, "!governance");
IStrategy(_strategy).withdraw(_token);
}

Expand All @@ -189,13 +173,7 @@ contract ControllerV4 {
) public view returns (uint256 expected) {
uint256 _balance = IERC20(_token).balanceOf(_strategy);
address _want = IStrategy(_strategy).want();
(expected, ) = OneSplitAudit(onesplit).getExpectedReturn(
_token,
_want,
_balance,
parts,
0
);
(expected, ) = OneSplitAudit(onesplit).getExpectedReturn(_token, _want, _balance, parts, 0);
}

// Only allows to withdraw non-core strategy tokens ~ this is over and above normal yield
Expand All @@ -204,10 +182,7 @@ contract ControllerV4 {
address _token,
uint256 parts
) public {
require(
msg.sender == strategist || msg.sender == governance,
"!governance"
);
require(msg.sender == strategist || msg.sender == governance, "!governance");
// This contract should never have value in it, but just incase since this is a public call
uint256 _before = IERC20(_token).balanceOf(address(this));
IStrategy(_strategy).withdraw(_token);
Expand All @@ -220,16 +195,8 @@ contract ControllerV4 {
_before = IERC20(_want).balanceOf(address(this));
IERC20(_token).safeApprove(onesplit, 0);
IERC20(_token).safeApprove(onesplit, _amount);
(_expected, _distribution) = OneSplitAudit(onesplit)
.getExpectedReturn(_token, _want, _amount, parts, 0);
OneSplitAudit(onesplit).swap(
_token,
_want,
_amount,
_expected,
_distribution,
0
);
(_expected, _distribution) = OneSplitAudit(onesplit).getExpectedReturn(_token, _want, _amount, parts, 0);
OneSplitAudit(onesplit).swap(_token, _want, _amount, _expected, _distribution, 0);
_after = IERC20(_want).balanceOf(address(this));
if (_after > _before) {
_amount = _after.sub(_before);
Expand Down Expand Up @@ -266,29 +233,21 @@ contract ControllerV4 {
address _toJarToken = IJar(_toJar).token();

// Get pTokens from msg.sender
IERC20(_fromJar).safeTransferFrom(
msg.sender,
address(this),
_fromJarAmount
);
IERC20(_fromJar).safeTransferFrom(msg.sender, address(this), _fromJarAmount);

// Calculate how much underlying
// is the amount of pTokens worth
uint256 _fromJarUnderlyingAmount = _fromJarAmount
.mul(IJar(_fromJar).getRatio())
.div(10**uint256(IJar(_fromJar).decimals()));
uint256 _fromJarUnderlyingAmount = _fromJarAmount.mul(IJar(_fromJar).getRatio()).div(
10**uint256(IJar(_fromJar).decimals())
);

// Call 'withdrawForSwap' on Jar's current strategy if Jar
// doesn't have enough initial capital.
// This has moves the funds from the strategy to the Jar's
// 'earnable' amount. Enabling 'free' withdrawals
uint256 _fromJarAvailUnderlying = IERC20(_fromJarToken).balanceOf(
_fromJar
);
uint256 _fromJarAvailUnderlying = IERC20(_fromJarToken).balanceOf(_fromJar);
if (_fromJarAvailUnderlying < _fromJarUnderlyingAmount) {
IStrategy(strategies[_fromJarToken]).withdrawForSwap(
_fromJarUnderlyingAmount.sub(_fromJarAvailUnderlying)
);
IStrategy(strategies[_fromJarToken]).withdrawForSwap(_fromJarUnderlyingAmount.sub(_fromJarAvailUnderlying));
}

// Withdraw from Jar
Expand All @@ -299,12 +258,8 @@ contract ControllerV4 {
IJar(_fromJar).withdraw(_fromJarAmount);

// Calculate fee
uint256 _fromUnderlyingBalance = IERC20(_fromJarToken).balanceOf(
address(this)
);
uint256 _convenienceFee = _fromUnderlyingBalance.mul(convenienceFee).div(
convenienceFeeMax
);
uint256 _fromUnderlyingBalance = IERC20(_fromJarToken).balanceOf(address(this));
uint256 _convenienceFee = _fromUnderlyingBalance.mul(convenienceFee).div(convenienceFeeMax);

if (_convenienceFee > 1) {
IERC20(_fromJarToken).safeTransfer(devfund, _convenienceFee.div(2));
Expand Down Expand Up @@ -333,37 +288,24 @@ contract ControllerV4 {
return _toJarBal;
}

function _execute(address _target, bytes memory _data)
internal
returns (bytes memory response)
{
function _execute(address _target, bytes memory _data) internal returns (bytes memory response) {
require(_target != address(0), "!target");

// call contract in current context
assembly {
let succeeded := delegatecall(
sub(gas(), 5000),
_target,
add(_data, 0x20),
mload(_data),
0,
0
)
let succeeded := delegatecall(sub(gas(), 5000), _target, add(_data, 0x20), mload(_data), 0, 0)
let size := returndatasize()

response := mload(0x40)
mstore(
0x40,
add(response, and(add(add(size, 0x20), 0x1f), not(0x1f)))
)
mstore(0x40, add(response, and(add(add(size, 0x20), 0x1f), not(0x1f))))
mstore(response, size)
returndatacopy(add(response, 0x20), 0, size)

switch iszero(succeeded)
case 1 {
// throw if delegatecall failed
revert(add(response, 0x20), size)
}
case 1 {
// throw if delegatecall failed
revert(add(response, 0x20), size)
}
}
}
}
Loading