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
36 changes: 36 additions & 0 deletions abi/TokenDistributor.json
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,29 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "address[]",
"name": "accounts",
"type": "address[]"
},
{
"internalType": "uint256[]",
"name": "amounts",
"type": "uint256[]"
},
{
"internalType": "uint208",
"name": "newTDV",
"type": "uint208"
}
],
"name": "migrateDropTokensAndTDV",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down Expand Up @@ -281,6 +304,19 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint208",
"name": "newTDV",
"type": "uint208"
}
],
"name": "setTDV",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "token",
Expand Down
7 changes: 7 additions & 0 deletions abi/Vault.json
Original file line number Diff line number Diff line change
Expand Up @@ -1131,6 +1131,13 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "upgradeCallBack",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down
8 changes: 3 additions & 5 deletions ignition/deployments/chain-8453/deployed_addresses.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,9 @@
"Main#InputModifierLib": "0x47F8FB8136BFAFb9791D4C0CBf8e0764b02D619e",
"Main#VaultInitLib": "0x262166E3d46dA3a796BF7BE448bdddfd11FFB56f",
"Main#VaultDepositLib": "0x60d879820974964b793B60a9FA14103B7f9527B0",
"Main#VaultSpendLib": "0x421DA02Cb0C0f457F96abF719A48ef61E78c3376",
"Main#VaultImplementation": "0xA92aA9b65d2D5b6C9a5Af2C4365357A304FC247B",
"Main#VaultSpendLib": "0x94CE27CDFD55208678FB250FeD21B7f1FfdEc4Ff",
"Main#VaultImplementation": "0xF136A71D02675DC797863DBab7fB4E30b63d7680",
"Main#VaultProxy": "0xE0Eefe4AA0cB32740aDFD8083AbeC255AaC3b379",
"Main#Vault": "0xE0Eefe4AA0cB32740aDFD8083AbeC255AaC3b379",
"Main#ProtocolManager": "0xCC499487F6a1780dB9410a65408B98E63346aCfe",
"VaultUpgradeProd#VaultSpendLib": "0x94CE27CDFD55208678FB250FeD21B7f1FfdEc4Ff",
"VaultUpgradeProd#VaultImplementation": "0x5Bb28C730A85D2C5Ea834592b6D06a444D607AB7"
"Main#ProtocolManager": "0xCC499487F6a1780dB9410a65408B98E63346aCfe"
}
19 changes: 3 additions & 16 deletions ignition/modules/VaultUpgrade.module.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,15 @@
import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";

export default buildModule("VaultUpgradeProd", (m) => {
export default buildModule("VaultUpgrade", (m) => {
const interestLib = m.contractAt("InterestLib", "0xe8426F0675C9Da7340b4E8801cDE6a5C59f23Eb7");
const vaultMathLib = m.contractAt("VaultMathLib", "0x67bCC483fAaD61c3B7eBAdb31c884b8Aba9A13Ff");

const inputsLib = m.contractAt("InputsLib", "0x8B77b2Bf6A592361aF18803d785c25a1BBE1104c");

const investmentVaultLib = m.contractAt("InvestmentVaultLib", "0x3B0775204AF03c2E9940CfbCB9fbeA0949CadA7B");

const inputModifierLib = m.contractAt("InputModifierLib", "0x47F8FB8136BFAFb9791D4C0CBf8e0764b02D619e");

const vaultDepositLib = m.contractAt("VaultDepositLib", "0x60d879820974964b793B60a9FA14103B7f9527B0");

const vaultSpendLib = m.library("VaultSpendLib", {
id: `VaultSpendLib_1`,
libraries: {
VaultMathLib: vaultMathLib,
InterestLib: interestLib,
InvestmentVaultLib: investmentVaultLib,
InputsLib: inputsLib,
},
after: [vaultDepositLib],
});
const vaultSpendLib = m.contractAt("VaultSpendLib", "0x94CE27CDFD55208678FB250FeD21B7f1FfdEc4Ff");

const vaultInitLib = m.contractAt("VaultInitLib", "0x262166E3d46dA3a796BF7BE448bdddfd11FFB56f");

Expand All @@ -34,8 +22,7 @@ export default buildModule("VaultUpgradeProd", (m) => {
VaultSpendLib: vaultSpendLib,
InterestLib: interestLib,
},
id: `Vault_1`,
after: [vaultSpendLib],
id: `Vault_5`,
});

return {
Expand Down
3 changes: 2 additions & 1 deletion scripts/encodeUpgradeCallBack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ const encodeUpgradeCallBack = () => {
// encode call upgradeCallBack
const vaultInterface = new hre.ethers.Interface(vaultAbi);
const callData = vaultInterface.encodeFunctionData("upgradeCallBack", []);
console.log(callData);
const hash = hre.ethers.keccak256(callData);
console.log(`callData: ${callData}, hash: ${hash}`);
};

encodeUpgradeCallBack();
4 changes: 2 additions & 2 deletions src/token/Token.sol
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ contract Token is ERC20Capped, ERC20Permit, Ownable {
* @dev The token is capped at 3,000,000 ZRL
*/
constructor()
ERC20("Zeroldger Token", "ZRL")
ERC20("ZeroLedger Token", "ZRL")
ERC20Capped(30_000_000 * 10 ** 18)
ERC20Permit("ZRL")
ERC20Permit("ZeroLedger Token")
Ownable(msg.sender)
{}

Expand Down
47 changes: 34 additions & 13 deletions src/token/TokenDistributor.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ struct MintingLayer {
contract TokenDistributor is ITokenDistributor, Ownable, ReentrancyGuard {
using Math for uint256;

/// @notice Address of the anchor token that this distributor distributes.
/// @notice Address of the anchor token that this distributor uses for TDV computation.
address public accountingToken;
/// @notice Address of the ZRL token that this distributor mints.
address public token;
Expand Down Expand Up @@ -59,8 +59,7 @@ contract TokenDistributor is ITokenDistributor, Ownable, ReentrancyGuard {
mintingLayers[3] = MintingLayer(3_750_000, 175 * 10 ** (LAYER_DECIMALS - 2)); // 1.75
mintingLayers[4] = MintingLayer(7_750_000, 75 * 10 ** (LAYER_DECIMALS - 2)); // 0.75
mintingLayers[5] = MintingLayer(15_750_000, 3125 * 10 ** (LAYER_DECIMALS - 4)); // 0.3125
mintingLayers[6] = MintingLayer(31_750_000, 125 * 10 ** (LAYER_DECIMALS - 3)); // 0.125 ZRL per 1 USDC (tokenomics
// table round 7)
mintingLayers[6] = MintingLayer(31_750_000, 125 * 10 ** (LAYER_DECIMALS - 3)); // 0.125
mintingLayers[7] = MintingLayer(63_750_000, 46875 * 10 ** (LAYER_DECIMALS - 6)); // 0.046875
mintingLayers[8] = MintingLayer(127_750_000, 15625 * 10 ** (LAYER_DECIMALS - 6)); // 0.015625
mintingLayers[9] = MintingLayer(255_750_000, 390625); // 0.00390625
Expand All @@ -69,6 +68,10 @@ contract TokenDistributor is ITokenDistributor, Ownable, ReentrancyGuard {
accountingToken = anchorToken_;
}

function setTDV(uint208 newTDV) public onlyOwner {
TDV = newTDV;
}

/// @inheritdoc ITokenDistributor
function distribute(address to, uint208 anchorAmount) external onlyOwner {
(uint256 toMint, uint208 newTDV) = _compute(TDV, anchorAmount);
Expand All @@ -78,7 +81,7 @@ contract TokenDistributor is ITokenDistributor, Ownable, ReentrancyGuard {

/// @inheritdoc ITokenDistributor
function previewDistribute(uint208 anchorAmount) external view returns (uint256 toMint) {
(toMint,) = _compute(TDV, anchorAmount);
(toMint, ) = _compute(TDV, anchorAmount);
}

/**
Expand All @@ -99,16 +102,21 @@ contract TokenDistributor is ITokenDistributor, Ownable, ReentrancyGuard {
uint208 leftTDVInLayer = uint208(mintingLayers[layer].TDVLayerCap * 10 ** anchorDecimals) - newTDV;

if (anchorAmountToProcess > leftTDVInLayer) {
toMintAcc +=
(leftTDVInLayer * anchorToTokenPow).mulDiv(mintingLayers[layer].multiplier, LAYER_POW, Math.Rounding.Floor);
toMintAcc += (leftTDVInLayer * anchorToTokenPow).mulDiv(
mintingLayers[layer].multiplier,
LAYER_POW,
Math.Rounding.Floor
);
layer = ++layer;
anchorAmountToProcess -= leftTDVInLayer;
newTDV = newTDV + leftTDVInLayer;
} else {
// base formula: anchorAmount * layer_multiplier
// with decimals: anchorAmount * 10 ** (token_decimals - decimals) * layer_multiplier / 10 ** LAYER_DECIMALS
toMintAcc += (uint256(anchorAmountToProcess) * anchorToTokenPow).mulDiv(
mintingLayers[layer].multiplier, LAYER_POW, Math.Rounding.Floor
mintingLayers[layer].multiplier,
LAYER_POW,
Math.Rounding.Floor
);
newTDV = newTDV + anchorAmountToProcess;
anchorAmountToProcess = 0;
Expand Down Expand Up @@ -153,13 +161,26 @@ contract TokenDistributor is ITokenDistributor, Ownable, ReentrancyGuard {
}

/// @inheritdoc ITokenDistributor
function claim(bytes32[] calldata proof, uint256 amount)
external
nonReentrant
onlyNotClaimed(msg.sender)
onlyValidProof(msg.sender, amount, proof)
{
function claim(
bytes32[] calldata proof,
uint256 amount
) external nonReentrant onlyNotClaimed(msg.sender) onlyValidProof(msg.sender, amount, proof) {
claimed[msg.sender] = true;
Token(token).mint(msg.sender, amount);
}

function migrateDropTokensAndTDV(
address[] calldata accounts,
uint256[] calldata amounts,
uint208 newTDV
) external onlyOwner {
if (TDV != 0) {
revert("migrated");
}
TDV = newTDV;
for (uint256 i = 0; i < accounts.length; i++) {
claimed[accounts[i]] = true;
Token(token).mint(accounts[i], amounts[i]);
}
}
}
7 changes: 5 additions & 2 deletions src/vault/Vault.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ import {State} from "src/vault/VaultStorage.sol";

/**
* @title Vault
* @notice The main Zeroledger contract and entry point for the protocol.
* @dev Zeroldger token & token distributor are immutable and cannot be upgraded.
* @notice The main ZeroLedger contract and entry point for the protocol.
* @dev ZeroLedger token & token distributor are immutable and cannot be upgraded.
* @author ZeroLedger
*/
contract Vault is
Expand Down Expand Up @@ -81,6 +81,8 @@ contract Vault is
);
}

function upgradeCallBack() external reinitializer(4) {}

/// @inheritdoc IVault
function approveUpgrade(address newImplementation, bytes32 paramsHash) external restricted {
_getStorage().approvedImplementation = newImplementation;
Expand All @@ -104,6 +106,7 @@ contract Vault is
*/
function upgradeToAndCall(address newImplementation, bytes memory data) public payable override onlyProxy {
State storage state = _getStorage();
require(state.approvedImplementation != address(0), "impl not approved");
require(state.approvedImplementation == newImplementation, "impl not approved");
require(keccak256(data) == state.approvedUpgradeParamsHash, "params not approved");
// clear to prevent reuse
Expand Down
Loading