Skip to content
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
48 changes: 48 additions & 0 deletions broadcast/mainnet/sYLAYV2Deploy.s.sol/1/run-1756833465412.json

Large diffs are not rendered by default.

48 changes: 48 additions & 0 deletions broadcast/mainnet/sYLAYV2Deploy.s.sol/1/run-latest.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion deployment/mainnet.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"proxy": "0x8e933387AFc6F0F67588e5Dac33EBa97eF988C69"
},
"sYLAY": {
"implementation": "0xa98855a0932f704fd37566Ec810E4d010Bf32BD7",
"implementation": "0xEA8e63346e8a6ae1a15aa41c14004D030622B67B",
"proxy": "0xC0F7B477e05B29097546dAae2E3dF2decBeB405d"
},
"sYLAYRewards": {
Expand Down
3 changes: 2 additions & 1 deletion foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ broadcast = 'broadcast/arbitrum-tenderly'
cache_path = 'cache/local'
broadcast = 'broadcast/local'

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options
[etherscan]
mainnet = { key = "${ETHERSCAN_API_KEY}" }
24 changes: 24 additions & 0 deletions script/sYLAYV2Deploy.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;

import {Script, console} from "forge-std/Script.sol";

import {Environment} from "./helpers.sol";

import {sYLAY} from "src/sYLAY.sol";
import {IYelayOwner} from "src/interfaces/IYelayOwner.sol";

/**
* source .env && FOUNDRY_PROFILE=mainnet forge script script/sYLAYV2Deploy.s.sol:sYLAYV2Deploy --slow --broadcast --legacy --etherscan-api-key $ETHERSCAN_API_KEY --verify
*/
contract sYLAYV2Deploy is Script {
function run() external {
Environment.setRpc(vm);

vm.startBroadcast(Environment.getPrivateKey(vm));
sYLAY sylay = new sYLAY(IYelayOwner(0xAB865D95A574511a6c893C38A4D892275ca70570));
vm.stopBroadcast();

console.log("sYLAY V2", address(sylay));
}
}
75 changes: 30 additions & 45 deletions src/sYLAY.sol
Original file line number Diff line number Diff line change
Expand Up @@ -296,9 +296,7 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
*/
function mint(address to, uint256 amount) external onlyMinter {
totalInstantPower += amount;
unchecked {
userInstantPower[to] += amount;
}
userInstantPower[to] += amount;
emit Minted(to, amount);
}

Expand All @@ -316,10 +314,8 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
*/
function burn(address from, uint256 amount) external onlyMinter {
require(userInstantPower[from] >= amount, "sYLAY:burn: User instant power balance too low");
unchecked {
userInstantPower[from] -= amount;
totalInstantPower -= amount;
}
userInstantPower[from] -= amount;
totalInstantPower -= amount;
emit Burned(from, amount);
}

Expand Down Expand Up @@ -424,9 +420,7 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
* @return trancheIndex tranche index at `time`
*/
function _getTrancheIndex(uint256 time) private view returns (uint16) {
unchecked {
return uint16(((time - firstTrancheStartTime) / TRANCHE_TIME) + 1);
}
return uint16(((time - firstTrancheStartTime) / TRANCHE_TIME) + 1);
}

/**
Expand Down Expand Up @@ -454,9 +448,7 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
* @return trancheIndex last finished tranche index
*/
function getLastFinishedTrancheIndex() public view returns (uint16) {
unchecked {
return getCurrentTrancheIndex() - 1;
}
return getCurrentTrancheIndex() - 1;
}

/* ---------- LOCKUP POWER: FUNCTIONS ---------- */
Expand Down Expand Up @@ -549,10 +541,8 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {

function _burnLockup(UserLockup memory userLockup, address to, uint256 start) internal returns (uint256 amount) {
// reduce global lockup powers
unchecked {
totalLockupPower -= userLockup.power;
userLockupPower[to] -= userLockup.power;
}
totalLockupPower -= userLockup.power;
userLockupPower[to] -= userLockup.power;

amount = userLockup.amount;

Expand Down Expand Up @@ -591,12 +581,10 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
uint256 addedPower = userLockup.amount * (deadline - userLockup.deadline) / FULL_POWER_TRANCHES_COUNT;

// update global lockup powers and adjust user specific lockup position
unchecked {
totalLockupPower += addedPower;
userLockupPower[msg.sender] += addedPower;
userLockup.power += uint56(addedPower);
userLockup.deadline = uint64(deadline);
}
totalLockupPower += addedPower;
userLockupPower[msg.sender] += addedPower;
userLockup.power += uint56(addedPower);
userLockup.deadline = uint64(deadline);

emit LockupContinued(msg.sender, start, addedPower, deadline);
}
Expand Down Expand Up @@ -625,10 +613,8 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
uint256 power = amount * period / FULL_POWER_TRANCHES_COUNT;

// update globals
unchecked {
totalLockupPower += power;
userLockupPower[to] += power;
}
totalLockupPower += power;
userLockupPower[to] += power;

// update user specific data
userLockup.amount += uint48(amount);
Expand Down Expand Up @@ -865,11 +851,9 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {

// if user still has some amount left, mint gradual from start
if (userTotalGradualAmount > trimmedAmount) {
unchecked {
uint48 userAmountLeft = userTotalGradualAmount - trimmedAmount;
// mint amount left
_mintGradual(from, userAmountLeft);
}
uint48 userAmountLeft = userTotalGradualAmount - trimmedAmount;
// mint amount left
_mintGradual(from, userAmountLeft);
}
}
}
Expand All @@ -895,7 +879,16 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
function _removeUserTrancheFromGlobal(UserTranche memory userTranche) private {
if (userTranche.amount > 0) {
Tranche storage tranche = _getTranche(userTranche.index);
tranche.amount -= userTranche.amount;
if (tranche.amount >= userTranche.amount) {
tranche.amount -= userTranche.amount;
} else {
// support rounding errors from migration
if (userTranche.amount - tranche.amount == 1) {
tranche.amount = 0;
} else {
revert("sYLAY::_removeUserTrancheFromGlobal: Tranche precision");
}
}
}
}

Expand Down Expand Up @@ -1248,9 +1241,7 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
function _getLastMaturedIndex() private view returns (uint16 lastMaturedIndex) {
uint256 currentTrancheIndex = getCurrentTrancheIndex();
if (currentTrancheIndex > FULL_POWER_TRANCHES_COUNT) {
unchecked {
lastMaturedIndex = uint16(currentTrancheIndex - FULL_POWER_TRANCHES_COUNT);
}
lastMaturedIndex = uint16(currentTrancheIndex - FULL_POWER_TRANCHES_COUNT);
}
}

Expand Down Expand Up @@ -1364,9 +1355,7 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
function _trimRoundUp(uint256 amount) private pure returns (uint48 trimmedAmount) {
trimmedAmount = _trim(amount);
if (_untrim(trimmedAmount) < amount) {
unchecked {
trimmedAmount++;
}
trimmedAmount++;
}
}

Expand All @@ -1377,9 +1366,7 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
* @return untrimmedAmount untrimmed amount
*/
function _untrim(uint256 trimmedAmount) private pure returns (uint256) {
unchecked {
return trimmedAmount * TRIM_SIZE;
}
return trimmedAmount * TRIM_SIZE;
}

/**
Expand All @@ -1400,9 +1387,7 @@ contract sYLAY is YelayOwnable, IsYLAY, IERC20MetadataUpgradeable {
* @return asRawUnmatured `amount` multiplied by `FULL_POWER_TRANCHES_COUNT` (raw unmatured amount)
*/
function _getMaturedAsRawUnmaturedAmount(uint48 amount) private pure returns (uint56) {
unchecked {
return uint56(amount * FULL_POWER_TRANCHES_COUNT);
}
return uint56(amount * FULL_POWER_TRANCHES_COUNT);
}

/**
Expand Down
63 changes: 63 additions & 0 deletions test/upgrades/sYLAYV2.t.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
// SPDX-License-Identifier: MIT

pragma solidity 0.8.13;

import {Test} from "forge-std/Test.sol";

import {TransparentUpgradeableProxy} from "openzeppelin-contracts/proxy/transparent/TransparentUpgradeableProxy.sol";
import {ProxyAdmin} from "openzeppelin-contracts/proxy/transparent/ProxyAdmin.sol";
import {IERC20} from "openzeppelin-contracts/interfaces/IERC20.sol";

import {IYelayOwner} from "src/interfaces/IYelayOwner.sol";
import {YelayStaking} from "src/YelayStaking.sol";
import {sYLAY} from "src/sYLAY.sol";

contract sYLAYV2Test is Test {
address owner = 0x4e736b96920a0f305022CBaAea493Ce7e49Eee6C;
ProxyAdmin proxyAdmin = ProxyAdmin(0x51c8FA2c1F093AC643f6431766b1c227d869Cb6F);
YelayStaking yelayStaking = YelayStaking(0x8e933387AFc6F0F67588e5Dac33EBa97eF988C69);
sYLAY sylay = sYLAY(0xC0F7B477e05B29097546dAae2E3dF2decBeB405d);
IERC20 ylay = IERC20(0xAEe5913FFd19dBcA4Fd1eF6F3925ed0414407d37);

function setUp() public {
uint256 mainnetForkId = vm.createFork(vm.rpcUrl("mainnet"), 23268420);
vm.selectFork(mainnetForkId);
}

function test_upgrade_and_unstake() external {
address user = 0xe058564c235f06f5dF394B68bE97dc4867f64c89;
sYLAY newsYLAY = new sYLAY(IYelayOwner(0xAB865D95A574511a6c893C38A4D892275ca70570));

uint256 stakingAmount = yelayStaking.balances(user);
uint256 balanceBefore = ylay.balanceOf(user);

assertGt(stakingAmount, 0, "Non zero staking amount");

vm.startPrank(user);
vm.expectRevert();
yelayStaking.unstake(stakingAmount);
vm.stopPrank();

assertEq(ylay.balanceOf(user), balanceBefore, "No YLAY balance change");

assertNotEq(
proxyAdmin.getProxyImplementation(TransparentUpgradeableProxy(payable(address(sylay)))), address(newsYLAY)
);

vm.startPrank(owner);
proxyAdmin.upgrade(TransparentUpgradeableProxy(payable(address(sylay))), address(newsYLAY));
vm.stopPrank();

assertEq(
proxyAdmin.getProxyImplementation(TransparentUpgradeableProxy(payable(address(sylay)))), address(newsYLAY)
);

vm.startPrank(user);
yelayStaking.unstake(stakingAmount);
vm.stopPrank();

uint256 balanceAfter = ylay.balanceOf(user);

assertEq(balanceAfter - balanceBefore, stakingAmount, "All YLAY is unstaked");
}
}