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

Stable2 + WellUpgradeable #135

Merged
merged 85 commits into from
Sep 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
85 commits
Select commit Hold shift + click to select a range
1d46422
init
Brean0 Jun 9, 2023
fc4aa20
added A parameter input, added well function tests.
Brean0 Jun 11, 2023
d346be1
Bore Tests, WellFunctionData.
Brean0 Jun 11, 2023
2deb61c
Merge remote-tracking branch 'refs/remotes/origin/master'
Brean0 Jun 24, 2023
72a8bb1
fix test helper
Brean0 Jun 24, 2023
798dbf1
add IWellErrors
Brean0 Jun 24, 2023
c9a751b
POC
Brean0 Jun 25, 2023
3868ea4
add liquidity tests, revise well function
Brean0 Jun 30, 2023
d55d529
beanstalkStableSwap inheriting, AddScaledReserves
Brean0 Jun 30, 2023
544aaf3
tests
Brean0 Jun 30, 2023
f8cc75b
scale down reserves in calcReserve
Brean0 Jun 30, 2023
16b8d3d
remove Stack too deep error, removeLiq one Tkn
Brean0 Jun 30, 2023
463fec4
remove Liquidity
Brean0 Jun 30, 2023
b30c004
Add Liquidity
Brean0 Jun 30, 2023
616f33d
mainnet gas comparisons
Brean0 Jul 4, 2023
e0a7faa
beanstalk stableswap decimal error
Brean0 Jul 4, 2023
0098c72
omit calcReserveAtRatio (TODO)
Brean0 Jul 14, 2023
ca995d7
Add upgrade changes
nickkatsios May 7, 2024
37b942b
Update wellUpgradable Implementation
Brean0 May 16, 2024
aa30e6b
update package.
Brean0 May 18, 2024
e9cfeee
Merge pull request #130 from BeanstalkFarms/well-upgradeable-impl-1
nickkatsios May 19, 2024
dd66d36
Update tests
Brean0 Jun 18, 2024
1fb2efb
Merge remote-tracking branch 'origin/multi-flow-pump-v1.1-remediation…
Brean0 Jun 21, 2024
3efa71f
WIP
Brean0 Jun 24, 2024
6a6da6b
WIP
Brean0 Jul 8, 2024
7fbcc2f
stable2
Brean0 Jul 9, 2024
e5cd490
priceReserveMapping2
Brean0 Jul 9, 2024
c897e7e
remove unneeded tests, update format
Brean0 Jul 12, 2024
a776b78
update LUT
Brean0 Jul 12, 2024
10c74e1
update LUT table, add liquidity test.
Brean0 Jul 13, 2024
e84145f
WIP
Brean0 Jul 14, 2024
4e637c1
add swap tests.
Brean0 Jul 15, 2024
81ac70a
gas optimization I
Brean0 Jul 15, 2024
3e79463
remove safeMath
Brean0 Jul 15, 2024
40fd126
cleanup I
Brean0 Jul 15, 2024
427ad85
Add stable2 calcSwap and calcLiquidity simulation scripts
nickkatsios Jul 16, 2024
fb2e36c
Update stable2 LUT tests
nickkatsios Jul 16, 2024
b7a44c0
Clean up various tests and contracts.
Brean0 Jul 23, 2024
6e4c647
add sims.
Brean0 Jul 23, 2024
f1f166c
Increase A parameter precision in LUT
Brean0 Jul 23, 2024
fd89761
update package.json
Brean0 Jul 23, 2024
70b3a23
Merge pull request #133 from BeanstalkFarms/master
Brean0 Jul 23, 2024
fd47d26
clean up wellUpgradeable.
Brean0 Jul 23, 2024
1bcc72d
Merge pull request #134 from BeanstalkFarms/well-upgradeable-impl
Brean0 Jul 23, 2024
2257db8
remove console logs.
Brean0 Jul 23, 2024
18b48eb
update forge
Brean0 Jul 23, 2024
4d40f45
update requirement.txt
Brean0 Jul 23, 2024
cd4ae5f
Update comment.
Brean0 Jul 24, 2024
ae77893
update authors.
Brean0 Jul 24, 2024
5fa7540
update package version.
Brean0 Jul 24, 2024
85b2e8b
Merge branch 'master' into stableswapWF-2
Brean0 Jul 26, 2024
c6de381
init
Brean0 Aug 13, 2024
abf09ab
remove unused test helper function.
Brean0 Aug 13, 2024
4eca74c
Add access control to authorizeUpgrade
nickkatsios Aug 14, 2024
07e9924
Add explicit revert statements in the case of non convergence
nickkatsios Aug 14, 2024
82a9f3c
impose limits on reserves, update formmating
Brean0 Aug 14, 2024
af35125
Add check for well tokens in authorizeUpgrade
nickkatsios Aug 14, 2024
0143ccf
decimal fix
nickkatsios Aug 14, 2024
812bca2
remove else statment in notDelegatedOrIsMinimalProxy modifier
nickkatsios Aug 14, 2024
453d388
update tests
Brean0 Aug 14, 2024
54ac748
update optimizer to compile.
Brean0 Aug 14, 2024
5d12098
update formmating
Brean0 Aug 14, 2024
6eac8fa
Merge pull request #142 from BeanstalkFarms/minimal-proxy-modifier-fix
nickkatsios Aug 21, 2024
163b53e
Merge pull request #141 from BeanstalkFarms/decimal1-fix
nickkatsios Aug 21, 2024
e824771
Merge pull request #140 from BeanstalkFarms/well-upgr-token-check
nickkatsios Aug 21, 2024
e60e660
Merge pull request #139 from BeanstalkFarms/s2-newton-revert
nickkatsios Aug 21, 2024
1b7ce53
Merge branch 's2-upgr-well-remediations' into well-upgr-access-control
nickkatsios Aug 21, 2024
1409811
fix tests
nickkatsios Aug 21, 2024
0e441af
Merge pull request #138 from BeanstalkFarms/well-upgr-access-control
nickkatsios Aug 21, 2024
55bd22b
Merge pull request #137 from BeanstalkFarms/calcReserve-edge
nickkatsios Aug 21, 2024
a9c1f68
update comment in well upgr test
nickkatsios Aug 21, 2024
3241f9c
update package version, formatting.
Brean0 Aug 21, 2024
7ee69fd
fix typo in _authorizeUpgrade
nickkatsios Aug 21, 2024
42a4dbc
clarify comment in calcReserveAtRatioSwap
nickkatsios Aug 21, 2024
6b51015
change proxiableUUID visibility to public
nickkatsios Aug 21, 2024
ec8e7e3
remove unreachable code blocks in stable2
nickkatsios Aug 21, 2024
ba1ce3f
remove redundant sumReserves check in calcLpTokenSupply
nickkatsios Aug 21, 2024
fa50f70
add venv files to gitignore
nickkatsios Aug 21, 2024
071cc41
Merge pull request #144 from BeanstalkFarms/qa-fixes
nickkatsios Aug 21, 2024
c6ce202
update package version.
Brean0 Aug 22, 2024
20bb66a
Add check for oscillation in calcLpTokenSupply.
Brean0 Aug 29, 2024
ff021fe
change absolute diff to relative diff, increase price precision.
Brean0 Aug 29, 2024
ff0936e
Merge pull request #145 from BeanstalkFarms/s2-upgr-well-remediations-2
Brean0 Sep 6, 2024
e8e47e9
Merge pull request #143 from BeanstalkFarms/s2-upgr-well-remediations
Brean0 Sep 6, 2024
c5507c5
update package version to v1.2.0.
Brean0 Sep 6, 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
6 changes: 6 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@
cache/
out/

# Python virtual environments
env/
venv/

.vscode

# Ignores development broadcast logs
/broadcast

Expand Down
3 changes: 1 addition & 2 deletions foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ out = 'out'
libs = ['lib', 'node_modules']
fuzz = { runs = 256 }
optimizer = true
optimizer_runs = 800
optimizer_runs = 200
remappings = [
'@openzeppelin/=node_modules/@openzeppelin/',
]
Expand All @@ -27,7 +27,6 @@ ignore = ["src/libraries/LibClone.sol", "src/utils/Clone.sol", "src/libraries/AB
int_types = "long"
line_length = 120
multiline_func_header = "params_first"
number_underscore = "thousands"
override_spacing = false
quote_style = "double"
tab_width = 4
Expand Down
14 changes: 14 additions & 0 deletions mocks/wells/MockWellUpgradeable.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

import {WellUpgradeable} from "src/WellUpgradeable.sol";

// this needs to be here for upgrade checks
/// @custom:oz-upgrades-from WellUpgradeable
contract MockWellUpgradeable is WellUpgradeable {

function getVersion(uint256 i) external pure returns (uint256) {
return i;
}
}
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@beanstalk/wells",
"version": "1.1.0",
"version": "1.2.0",
"description": "A [{Well}](/src/Well.sol) is a constant function AMM that allows the provisioning of liquidity into a single pooled on-chain liquidity position.",
"main": "index.js",
"directories": {
Expand Down
19 changes: 16 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
eth-abi==3.0.1
pandas
numpy
cytoolz==0.12.3
eth-hash==0.7.0
eth-typing==3.5.2
eth-utils==2.3.1
eth_abi==5.1.0
numpy==2.0.1
pandas==2.2.2
parsimonious==0.10.0
python-dateutil==2.9.0.post0
pytz==2024.1
regex==2024.5.15
setuptools==71.1.0
six==1.16.0
toolz==0.12.1
typing_extensions==4.12.2
tzdata==2024.1
24 changes: 24 additions & 0 deletions script/helpers/WellDeployer.sol
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import {LibContractInfo} from "src/libraries/LibContractInfo.sol";
import {LibWellConstructor} from "src/libraries/LibWellConstructor.sol";
import {Well, Call, IERC20} from "src/Well.sol";
import {Aquifer} from "src/Aquifer.sol";
import {WellUpgradeable} from "src/WellUpgradeable.sol";
import {LibWellUpgradeableConstructor} from "src/libraries/LibWellUpgradeableConstructor.sol";

abstract contract WellDeployer {
/**
Expand All @@ -28,4 +30,26 @@ abstract contract WellDeployer {
LibWellConstructor.encodeWellDeploymentData(_aquifer, _tokens, _wellFunction, _pumps);
_well = Well(Aquifer(_aquifer).boreWell(_wellImplementation, immutableData, initData, _salt));
}

/**
* @notice Encode the Well's immutable data, and deploys the well. Modified for upgradeable wells.
* @param _aquifer The address of the Aquifer which will deploy this Well.
* @param _wellImplementation The address of the Well implementation.
* @param _tokens A list of ERC20 tokens supported by the Well.
* @param _wellFunction A single Call struct representing a call to the Well Function.
* @param _pumps An array of Call structs representings calls to Pumps.
* @param _salt The salt to deploy the Well with (`bytes32(0)` for none). See {LibClone}.
*/
function encodeAndBoreWellUpgradeable(
address _aquifer,
address _wellImplementation,
IERC20[] memory _tokens,
Call memory _wellFunction,
Call[] memory _pumps,
bytes32 _salt
) internal returns (WellUpgradeable _well) {
(bytes memory immutableData, bytes memory initData) =
LibWellUpgradeableConstructor.encodeWellDeploymentData(_aquifer, _tokens, _wellFunction, _pumps);
_well = WellUpgradeable(Aquifer(_aquifer).boreWell(_wellImplementation, immutableData, initData, _salt));
}
}
99 changes: 99 additions & 0 deletions script/simulations/stableswap/StableswapCalcRatiosLiqSim.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

import "forge-std/Script.sol";
import {console} from "forge-std/console.sol";
import {Stable2} from "src/functions/Stable2.sol";
import {Stable2LUT1} from "src/functions/StableLUT/Stable2LUT1.sol";

/**
* Stable2 well function simulation and precalculations used
* to produce the token ratios for the lookup table needed for the initial
* `calcReserveAtRatioLiquidity` estimates.
*/
contract StableswapCalcRatiosLiqSim is Script {
function run() external {
Stable2LUT1 stable2LUT1 = new Stable2LUT1();
Stable2 stable2 = new Stable2(address(stable2LUT1));
console.log("stable2.getAParameter(): %d", stable2LUT1.getAParameter());
// initial reserves
uint256 init_reserve_x = 1_000_000e18;
uint256 init_reserve_y = 1_000_000e18;
uint256[] memory reserves = new uint256[](2);
reserves[0] = init_reserve_x;
reserves[1] = init_reserve_y;
uint256 reserve_y = init_reserve_y;
bytes memory data = abi.encode(18, 18);
uint256 price;

// for n times (1...n) :
// 1) modify reserve x_n-1 by some percentage (this changes the pool liquidity)
// 3) calc price_n using calcRate(...)

// csv header
console.log("Price (P),Reserve (x),Reserve (y)");

// calcReserveAtRatioLiquidity
for (uint256 i; i < 20; i++) {
// update reserves
reserve_y = reserve_y * 88 / 100;
reserves[1] = reserve_y;
// mark price
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, init_reserve_x, reserve_y);
}

// reset reserves
reserve_y = init_reserve_y;

// calcReserveAtRatioLiquidity
for (uint256 i; i < 20; i++) {
// update reserves
reserve_y = reserve_y * 98 / 100;
reserves[1] = reserve_y;
// mark price
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, init_reserve_x, reserve_y);
}

// reset reserves
reserve_y = init_reserve_y;

// calcReserveAtRatioLiquidity
for (uint256 i; i < 20; i++) {
// update reserves
reserve_y = reserve_y * 102 / 100;
reserves[1] = reserve_y;
// mark price
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, init_reserve_x, reserve_y);
}

// reset reserves
reserve_y = init_reserve_y;

// calcReserveAtRatioLiquidity
for (uint256 i; i < 20; i++) {
// update reserves
reserve_y = reserve_y * 112 / 100;
reserves[1] = reserve_y;
// mark price
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, init_reserve_x, reserve_y);
}

// Extreme prices

// extreme low
reserve_y = init_reserve_y * 1 / 28;
reserves[1] = reserve_y;
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, init_reserve_x, reserve_y);

// extreme high
reserve_y = init_reserve_y * 2000;
reserves[1] = reserve_y;
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, init_reserve_x, reserve_y);
}
}
119 changes: 119 additions & 0 deletions script/simulations/stableswap/StableswapCalcRatiosSwapSim.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.20;

import "forge-std/Script.sol";
import {console} from "forge-std/console.sol";
import {Stable2} from "src/functions/Stable2.sol";
import {Stable2LUT1} from "src/functions/StableLUT/Stable2LUT1.sol";

/**
* Stable2 well function simulation and precalculations used
* to produce the token ratios for the lookup table needed for the initial
* `calcReserveAtRatioSwap` estimates.
*/
contract StableswapCalcRatiosSwapSim is Script {
function run() external {
Stable2LUT1 stable2LUT1 = new Stable2LUT1();
Stable2 stable2 = new Stable2(address(stable2LUT1));
console.log("stable2.getAParameter(): %d", stable2LUT1.getAParameter());
// initial reserves
uint256 init_reserve_x = 1_000_000e18;
uint256 init_reserve_y = 1_000_000e18;
uint256[] memory reserves = new uint256[](2);
reserves[0] = init_reserve_x;
reserves[1] = init_reserve_y;
bytes memory data = abi.encode(18, 18);
// calculateLP token supply (this remains unchanged)
uint256 lpTokenSupply = stable2.calcLpTokenSupply(reserves, data);
console.log("lp_token_supply: %d", lpTokenSupply);
uint256 reserve_x = init_reserve_x;
uint256 price;

// for n times (1...n) :
// 1) increment x_n-1 by some amount to get x_n
// 2) calc y_n using calcReserves(...)
// 3) calc price_n using calcRate(...)

// csv header
console.log("Price (P),Reserve (x),Reserve (y)");

for (uint256 i; i < 20; i++) {
// update reserve x
reserve_x = reserve_x * 92 / 100;
reserves[0] = reserve_x;
// get y_n --> corresponding reserve y for a given liquidity level
uint256 reserve_y = stable2.calcReserve(reserves, 1, lpTokenSupply, data);
// update reserve y
reserves[1] = reserve_y;
// mark price
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, reserve_x, reserve_y);
}

// reset reserves
reserve_x = init_reserve_x;

for (uint256 i; i < 40; i++) {
// update reserve x
reserve_x = reserve_x * 99 / 100;
reserves[0] = reserve_x;
// get y_n --> corresponding reserve y for a given liquidity level
uint256 reserve_y = stable2.calcReserve(reserves, 1, lpTokenSupply, data);
// update reserve y
reserves[1] = reserve_y;
// mark price
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, reserve_x, reserve_y);
}

// reset reserves
reserve_x = init_reserve_x;

for (uint256 i; i < 40; i++) {
// update reserve x
reserve_x = reserve_x * 101 / 100;
reserves[0] = reserve_x;
// get y_n --> corresponding reserve y for a given liquidity level
uint256 reserve_y = stable2.calcReserve(reserves, 1, lpTokenSupply, data);
// update reserve y
reserves[1] = reserve_y;
// mark price
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, reserve_x, reserve_y);
}

// reset reserves
reserve_x = init_reserve_x;

for (uint256 i; i < 18; i++) {
// update reserve x
reserve_x = reserve_x * 105 / 100;
reserves[0] = reserve_x;
// get y_n --> corresponding reserve y for a given liquidity level
uint256 reserve_y = stable2.calcReserve(reserves, 1, lpTokenSupply, data);
// update reserve y
reserves[1] = reserve_y;
// mark price
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, reserve_x, reserve_y);
}

// Extreme prices

// extreme low
reserve_x = init_reserve_x * 3;
reserves[0] = reserve_x;
uint256 reserve_y = stable2.calcReserve(reserves, 1, lpTokenSupply, data);
reserves[1] = reserve_y;
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, reserve_x, reserve_y);

// extreme high
reserve_x = init_reserve_x * 1 / 190;
reserves[0] = reserve_x;
reserve_y = stable2.calcReserve(reserves, 1, lpTokenSupply, data);
reserves[1] = reserve_y;
price = stable2.calcRate(reserves, 0, 1, data);
console.log("%d,%d,%d", price, reserve_x, reserve_y);
}
}
Loading
Loading