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

feat: UUPS upgradeable #5

Merged
merged 1 commit into from
Mar 29, 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
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@
[submodule "lib/staking"]
path = lib/staking
url = https://github.com/tenderize/staking
[submodule "lib/openzeppelin-contracts-upgradeable"]
path = lib/openzeppelin-contracts-upgradeable
url = https://github.com/OpenZeppelin/openzeppelin-contracts-upgradeable
1 change: 1 addition & 0 deletions lib/openzeppelin-contracts-upgradeable
2 changes: 1 addition & 1 deletion script/Add_Liquidity.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ contract Add_Liquidity is Script {

function run() public {
vm.startBroadcast(deployerPrivateKey);
TenderSwap swap = TenderSwap(0x4ec6faD51A1957cAb7E8a62e43f0A0a0c2143d3f);
TenderSwap swap = TenderSwap(0x2C7b29B0d07276bA2DF4abE02E9A38b5693af9c6);
ERC20(underlying).approve(address(swap), 500_000 ether);
swap.deposit(500_000 ether);
console2.log("liabilities", swap.liabilities());
Expand Down
38 changes: 38 additions & 0 deletions script/Stats.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.17;

import { Script, console2 } from "forge-std/Script.sol";
import { ERC20 } from "solmate/tokens/ERC20.sol";
import { TenderSwap, Config } from "@tenderize/swap/Swap.sol";
import { SD59x18 } from "@prb/math/SD59x18.sol";
import { Tenderizer } from "@tenderize/stake/tenderizer/Tenderizer.sol";
import { StakingXYZ } from "lib/staking/test/helpers/StakingXYZ.sol";

contract Stats is Script {
function run() public {
address tenderswap = vm.envAddress("TENDERSWAP");
TenderSwap swap = TenderSwap(tenderswap);
console2.log(
"staking xyz %s",
StakingXYZ(0xd6d72408586887E37Cf299dbb50181892D3b184e).staked(0xE3350e66D3850B4f4C97b6737E9e8Ff78CFC1b00)
);
console2.log("tenderizer asset %s", Tenderizer(0xE3350e66D3850B4f4C97b6737E9e8Ff78CFC1b00).asset());
console2.log("tenderizer validator %s", Tenderizer(0xE3350e66D3850B4f4C97b6737E9e8Ff78CFC1b00).validator());

console2.log(
"tenderizer bal %s",
Tenderizer(0xE3350e66D3850B4f4C97b6737E9e8Ff78CFC1b00).balanceOf(0xF569CE1f749f073D6B85166141544288b3e24c2B)
);

console2.log("tenderizer supply %s", ERC20(address(0xE3350e66D3850B4f4C97b6737E9e8Ff78CFC1b00)).totalSupply());
ERC20(address(0xE3350e66D3850B4f4C97b6737E9e8Ff78CFC1b00)).approve(tenderswap, 1 ether);
swap.swap(address(0xE3350e66D3850B4f4C97b6737E9e8Ff78CFC1b00), 1 ether, 0);
uint256 liabilities = swap.liabilities();
uint256 liquidity = swap.liquidity();
SD59x18 utilisation = swap.utilisation();

console2.log("liabilities %s", liabilities);
console2.log("liquidity %s", liquidity);
console2.log("utilisation %s", utilisation.unwrap());
}
}
4 changes: 2 additions & 2 deletions src/LPToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ contract LPToken is ERC20 {
}

function _encodeName(string memory _name) internal pure returns (string memory) {
return string(abi.encodePacked("TenderSwap", " ", _name));
return string.concat("TenderSwap", " ", _name);
}

function _encodeSymbol(string memory _symbol) internal pure returns (string memory) {
return string(abi.encodePacked("tSWAP", " ", _symbol));
return string.concat("tSWAP", " ", _symbol);
}
}
18 changes: 17 additions & 1 deletion src/Swap.sol
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ import { Tenderizer, TenderizerImmutableArgs } from "@tenderize/stake/tenderizer
import { Unlocks } from "@tenderize/stake/unlocks/Unlocks.sol";
import { SafeCastLib } from "solmate/utils/SafeCastLib.sol";

import { OwnableUpgradeable } from "openzeppelin-contracts-upgradeable/access/OwnableUpgradeable.sol";
import { Initializable } from "openzeppelin-contracts-upgradeable/proxy/utils/Initializable.sol";
import { UUPSUpgradeable } from "openzeppelin-contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";

import { Multicall } from "@tenderize/swap/util/Multicall.sol";
import { SelfPermit } from "@tenderize/swap/util/SelfPermit.sol";
import { ERC721Receiver } from "@tenderize/swap/util/ERC721Receiver.sol";
Expand All @@ -29,6 +33,7 @@ import { UnlockQueue } from "@tenderize/swap/UnlockQueue.sol";
pragma solidity >=0.8.19;

// TODO: UUPS upgradeable
// TODO: fix '_utilisation' to use UD60x18

SD59x18 constant BASE_FEE = SD59x18.wrap(0.0005e18);
UD60x18 constant RELAYER_CUT = UD60x18.wrap(0.1e18);
Expand Down Expand Up @@ -80,7 +85,7 @@ abstract contract SwapStorage {
}
}

contract TenderSwap is SwapStorage, Multicall, SelfPermit, ERC721Receiver {
contract TenderSwap is Initializable, UUPSUpgradeable, OwnableUpgradeable, SwapStorage, Multicall, SelfPermit, ERC721Receiver {
using SafeTransferLib for ERC20;
using SafeCastLib for uint256;
using UnlockQueue for UnlockQueue.Data;
Expand All @@ -104,11 +109,18 @@ contract TenderSwap is SwapStorage, Multicall, SelfPermit, ERC721Receiver {
address private immutable registry;
address private immutable unlocks;

function intialize() public initializer {
__Ownable_init();
__UUPSUpgradeable_init();
}

/// @custom:oz-upgrades-unsafe-allow constructor
constructor(Config memory config) {
lpToken = new LPToken(config.underlying.name(), config.underlying.symbol());
underlying = config.underlying;
registry = config.registry;
unlocks = config.unlocks;
_disableInitializers();
}

modifier supplyUpdateHook(address asset) {
Expand Down Expand Up @@ -545,6 +557,10 @@ contract TenderSwap is SwapStorage, Multicall, SelfPermit, ERC721Receiver {

return amount * supply / $.liabilities;
}

///@dev required by the OZ UUPS module
// solhint-disable-next-line no-empty-blocks
function _authorizeUpgrade(address) internal override onlyOwner { }
}

function _encodeTokenId(address tenderizer, uint96 id) pure returns (uint256) {
Expand Down
15 changes: 15 additions & 0 deletions test/z3/quote.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
UNIT = 1e18
BASE_FEE = 0.005


def quote(x, u, U, s, S, L, K):
sumA = ((u + x) * K - U + u) * ((U + x) / L)**K

sumB = (U - u - K * u) * (U / L)**K

nom = (sumA + sumB) * (S + U)
denom = K * (UNIT + K) * (s + u)

fee = BASE_FEE * x + nom / denom
out = x - fee
return (out, fee)
48 changes: 48 additions & 0 deletions test/z3/quote_solver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
from z3 import Solver, Int, sat
import quote

# Define Z3 variables corresponding to Solidity function inputs and parameters
amount = Int('amount')
L = Int('L') # Liability
U = Int('U') # Example parameter from SwapParams
x = Int('x') # Corresponds to 'amount' in Solidity
K = Int('K') # Some constant from your function
BASE_FEE = Int('BASE_FEE') # Base fee constant
UNIT = Int('1')

# SwapParams in Z3 (simplified)
p_u = Int('p_u')
p_U = Int('p_U')
p_s = Int('p_s')
p_S = Int('p_S')

s = Solver()

# Generate random values (as an example)
# random_amount = random.uniform(0, 1000) # Random value between 0 and 1000
# ... generate other random values as needed

# Add random values as constraints
# s.add(amount == random_amount)

# Define bounds (as an example)
# lower_bound = 10
# upper_bound = 500

# Add constraints for bounds
# s.add(amount >= lower_bound, amount <= upper_bound)

# Simplified representation of the fee calculation logic
# Note: This is highly simplified and should be replaced with the actual logic
(out, fee) = quote.quote(amount, p_u, p_U, p_s, p_S, L, K)

# Define invariants

s.add(out <= amount, fee <= amount, out + fee ==
amount, out <= L - U, amount <= p_s)

# Check if the invariants are satisfiable
if s.check() == sat:
print("Invariants are satisfiable. Function behaves as expected under these conditions.")
else:
print("Invariants are not satisfiable. Function may have an issue or the model may need refinement.")
Loading