Skip to content

Commit

Permalink
Merge pull request #38 from 0xPolygon/revert-37-feat/emission-adjustment
Browse files Browse the repository at this point in the history
Revert "change staking emission from 1 to 2 percent"
  • Loading branch information
gretzke authored Oct 17, 2023
2 parents 09537fe + 3a30af3 commit a42673f
Show file tree
Hide file tree
Showing 6 changed files with 22 additions and 38 deletions.
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
/coverage
lcov.info
.DS_Store
.vscode
broadcast/
.env

Expand Down
16 changes: 8 additions & 8 deletions src/DefaultEmissionManager.sol
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import {SafeERC20} from "openzeppelin-contracts/contracts/token/ERC20/utils/Safe
import {PowUtil} from "./lib/PowUtil.sol";

/// @title Default Emission Manager
/// @author Polygon Labs (@DhairyaSethi, @gretzke, @qedk, @simonDos)
/// @author Polygon Labs (@DhairyaSethi, @gretzke, @qedk)
/// @notice A default emission manager implementation for the Polygon ERC20 token contract on Ethereum L1
/// @dev The contract allows for a 3% mint per year (compounded). 2% stakeManager(Hub) and 1% treasury
/// @dev The contract allows for a 1% mint *each* per year (compounded every year) to the stakeManager and treasury contracts
/// @custom:security-contact [email protected]
contract DefaultEmissionManager is Ownable2StepUpgradeable, IDefaultEmissionManager {
using SafeERC20 for IPolygonEcosystemToken;

// log2(3%pa continuously compounded emission per year) in 18 decimals, see _inflatedSupplyAfter
uint256 public constant INTEREST_PER_YEAR_LOG2 = 0.04264433740849372e18;
// log2(2%pa continuously compounded emission per year) in 18 decimals, see _inflatedSupplyAfter
uint256 public constant INTEREST_PER_YEAR_LOG2 = 0.028569152196770894e18;
uint256 public constant START_SUPPLY = 10_000_000_000e18;
address private immutable DEPLOYER;

Expand Down Expand Up @@ -65,7 +65,7 @@ contract DefaultEmissionManager is Ownable2StepUpgradeable, IDefaultEmissionMana
uint256 amountToMint = newSupply - currentSupply;
if (amountToMint == 0) return; // no minting required

uint256 treasuryAmt = amountToMint / 3;
uint256 treasuryAmt = amountToMint / 2;
uint256 stakeManagerAmt = amountToMint - treasuryAmt;

emit TokenMint(amountToMint, msg.sender);
Expand All @@ -79,10 +79,10 @@ contract DefaultEmissionManager is Ownable2StepUpgradeable, IDefaultEmissionMana

/// @notice Returns total supply from compounded emission after timeElapsed from startTimestamp (deployment)
/// @param timeElapsed The time elapsed since startTimestamp
/// @dev interestRatePerYear = 1.03; 3% per year
/// @dev interestRatePerYear = 1.02; 2% per year
/// approximate the compounded interest rate using x^y = 2^(log2(x)*y)
/// where x is the interest rate per year and y is the number of seconds elapsed since deployment divided by 365 days in seconds
/// log2(interestRatePerYear) = 0.04264433740849372 with 18 decimals, as the interest rate does not change, hard code the value
/// log2(interestRatePerYear) = 0.028569152196770894 with 18 decimals, as the interest rate does not change, hard code the value
/// @return supply total supply from compounded emission after timeElapsed
function inflatedSupplyAfter(uint256 timeElapsed) public pure returns (uint256 supply) {
uint256 supplyFactor = PowUtil.exp2((INTEREST_PER_YEAR_LOG2 * timeElapsed) / 365 days);
Expand All @@ -92,7 +92,7 @@ contract DefaultEmissionManager is Ownable2StepUpgradeable, IDefaultEmissionMana
/// @notice Returns the implementation version
/// @return Version string
function getVersion() external pure returns (string memory) {
return "1.1.0";
return "1.0.0";
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/PolygonEcosystemToken.sol
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {AccessControlEnumerable} from "openzeppelin-contracts/contracts/access/A
import {IPolygonEcosystemToken} from "./interfaces/IPolygonEcosystemToken.sol";

/// @title Polygon ERC20 token
/// @author Polygon Labs (@DhairyaSethi, @gretzke, @qedk, @simonDos)
/// @author Polygon Labs (@DhairyaSethi, @gretzke, @qedk)
/// @notice This is the Polygon ERC20 token contract on Ethereum L1
/// @dev The contract allows for a 1-to-1 representation between $POL and $MATIC and allows for additional emission based on hub and treasury requirements
/// @custom:security-contact [email protected]
Expand All @@ -15,7 +15,7 @@ contract PolygonEcosystemToken is ERC20Permit, AccessControlEnumerable, IPolygon
bytes32 public constant CAP_MANAGER_ROLE = keccak256("CAP_MANAGER_ROLE");
bytes32 public constant PERMIT2_REVOKER_ROLE = keccak256("PERMIT2_REVOKER_ROLE");
address public constant PERMIT2 = 0x000000000022D473030F116dDEE9F6B43aC78BA3;
uint256 public mintPerSecondCap = 13.37e18; // 13.37 POL tokens per second. will limit emission in ~23 years
uint256 public mintPerSecondCap = 10e18; // 10 POL tokens per second
uint256 public lastMint;
bool public permit2Enabled;

Expand Down Expand Up @@ -78,7 +78,7 @@ contract PolygonEcosystemToken is ERC20Permit, AccessControlEnumerable, IPolygon
/// this contract not being behind a proxy
/// @return Version string
function getVersion() external pure returns (string memory) {
return "1.1.0";
return "1.0.0";
}

function _updatePermit2Allowance(bool enabled) private {
Expand Down
33 changes: 9 additions & 24 deletions test/DefaultEmissionManager.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,9 @@ contract DefaultEmissionManagerTest is Test {
uint256 newSupply = abi.decode(vm.ffi(inputs), (uint256));

assertApproxEqAbs(newSupply, polygon.totalSupply(), _MAX_PRECISION_DELTA);
uint256 totalAmtMinted = polygon.totalSupply() - initialTotalSupply;
uint256 totalAmtMintedOneThird = totalAmtMinted / 3;
assertEq(matic.balanceOf(stakeManager), totalAmtMinted - totalAmtMintedOneThird);
assertEq(matic.balanceOf(treasury), 0);
assertEq(matic.balanceOf(stakeManager), (polygon.totalSupply() - initialTotalSupply) / 2);
assertEq(polygon.balanceOf(stakeManager), 0);
assertEq(polygon.balanceOf(treasury), totalAmtMintedOneThird);
assertEq(polygon.balanceOf(treasury), (polygon.totalSupply() - initialTotalSupply) / 2);
}

function test_MintDelayTwice(uint128 delay) external {
Expand All @@ -164,9 +161,8 @@ contract DefaultEmissionManagerTest is Test {
uint256 newSupply = abi.decode(vm.ffi(inputs), (uint256));

assertApproxEqAbs(newSupply, polygon.totalSupply(), _MAX_PRECISION_DELTA);
uint256 balance = (polygon.totalSupply() - initialTotalSupply) / 3;
uint256 stakeManagerBalance = (polygon.totalSupply() - initialTotalSupply) - balance;
assertEq(matic.balanceOf(stakeManager), stakeManagerBalance);
uint256 balance = (polygon.totalSupply() - initialTotalSupply) / 2;
assertEq(matic.balanceOf(stakeManager), balance);
assertEq(polygon.balanceOf(stakeManager), 0);
assertEq(polygon.balanceOf(treasury), balance);

Expand All @@ -179,13 +175,8 @@ contract DefaultEmissionManagerTest is Test {
newSupply = abi.decode(vm.ffi(inputs), (uint256));

assertApproxEqAbs(newSupply, polygon.totalSupply(), _MAX_PRECISION_DELTA);
uint256 totalAmtMinted = polygon.totalSupply() - initialTotalSupply;
uint256 totalAmtMintedOneThird = totalAmtMinted / 3;

balance += totalAmtMintedOneThird;
stakeManagerBalance += totalAmtMinted - totalAmtMintedOneThird;

assertEq(matic.balanceOf(stakeManager), stakeManagerBalance);
balance += (polygon.totalSupply() - initialTotalSupply) / 2;
assertEq(matic.balanceOf(stakeManager), balance);
assertEq(polygon.balanceOf(stakeManager), 0);
assertEq(polygon.balanceOf(treasury), balance);
}
Expand All @@ -194,7 +185,6 @@ contract DefaultEmissionManagerTest is Test {
vm.assume(delay * uint256(cycles) <= 10 * 365 days && delay > 0 && cycles < 30);

uint256 balance;
uint256 stakeManagerBalance;

for (uint256 cycle; cycle < cycles; cycle++) {
uint256 initialTotalSupply = polygon.totalSupply();
Expand All @@ -207,13 +197,8 @@ contract DefaultEmissionManagerTest is Test {
uint256 newSupply = abi.decode(vm.ffi(inputs), (uint256));

assertApproxEqAbs(newSupply, polygon.totalSupply(), _MAX_PRECISION_DELTA);
uint256 totalAmtMinted = polygon.totalSupply() - initialTotalSupply;
uint256 totalAmtMintedOneThird = totalAmtMinted / 3;

balance += totalAmtMintedOneThird;
stakeManagerBalance += totalAmtMinted - totalAmtMintedOneThird;

assertEq(matic.balanceOf(stakeManager), stakeManagerBalance);
balance += (polygon.totalSupply() - initialTotalSupply) / 2;
assertEq(matic.balanceOf(stakeManager), balance);
assertEq(polygon.balanceOf(stakeManager), 0);
assertEq(polygon.balanceOf(treasury), balance);
}
Expand All @@ -224,6 +209,6 @@ contract DefaultEmissionManagerTest is Test {
inputs[2] = vm.toString(delay);
inputs[3] = vm.toString(polygon.totalSupply());
uint256 newSupply = abi.decode(vm.ffi(inputs), (uint256));
assertApproxEqAbs(newSupply, emissionManager.inflatedSupplyAfter(block.timestamp + delay), 1e20);
assertApproxEqAbs(newSupply, emissionManager.inflatedSupplyAfter(block.timestamp + delay), 1e19);
}
}
2 changes: 1 addition & 1 deletion test/PolygonEcosystemToken.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ contract PolygonTest is Test {
address public governance;
address public permit2revoker;
DefaultEmissionManager public emissionManager;
uint256 public mintPerSecondCap = 13.37e18; // 13.37 POL tokens per second
uint256 public mintPerSecondCap = 10e18; // 10 POL tokens per second

function setUp() external {
migration = makeAddr("migration");
Expand Down
2 changes: 1 addition & 1 deletion test/util/calc.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const interestRatePerYear = 1.03;
const interestRatePerYear = 1.02;
const startSupply = 10_000_000_000e18;
function main() {
const [timeElapsedInSeconds] = process.argv.slice(2);
Expand Down

0 comments on commit a42673f

Please sign in to comment.