Skip to content

Commit

Permalink
JBFundingCycleMetadataResolver fixes + packing util method (jbx-proto…
Browse files Browse the repository at this point in the history
…col#38)

* JBFundingCycleMetadataResolver fixes + packing util method

* Address review comments
  • Loading branch information
dhyon authored Dec 9, 2021
1 parent af4fd4e commit e065870
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 36 deletions.
64 changes: 32 additions & 32 deletions contracts/libraries/JBFundingCycleMetadataResolver.sol
Original file line number Diff line number Diff line change
Expand Up @@ -25,67 +25,67 @@ library JBFundingCycleMetadataResolver {
}

function payPaused(JBFundingCycle memory _fundingCycle) internal pure returns (bool) {
return ((_fundingCycle.metadata >> 56) & 1) == 0;
return ((_fundingCycle.metadata >> 56) & 1) == 1;
}

function distributionsPaused(JBFundingCycle memory _fundingCycle) internal pure returns (bool) {
return ((_fundingCycle.metadata >> 57) & 1) == 0;
return ((_fundingCycle.metadata >> 57) & 1) == 1;
}

function redeemPaused(JBFundingCycle memory _fundingCycle) internal pure returns (bool) {
return ((_fundingCycle.metadata >> 58) & 1) == 0;
return ((_fundingCycle.metadata >> 58) & 1) == 1;
}

function mintPaused(JBFundingCycle memory _fundingCycle) internal pure returns (bool) {
return ((_fundingCycle.metadata >> 59) & 1) == 0;
return ((_fundingCycle.metadata >> 59) & 1) == 1;
}

function burnPaused(JBFundingCycle memory _fundingCycle) internal pure returns (bool) {
return ((_fundingCycle.metadata >> 60) & 1) == 0;
return ((_fundingCycle.metadata >> 60) & 1) == 1;
}

function changeTokenAllowed(JBFundingCycle memory _fundingCycle) internal pure returns (bool) {
return ((_fundingCycle.metadata >> 61) & 1) == 0;
return ((_fundingCycle.metadata >> 61) & 1) == 1;
}

function terminalMigrationAllowed(JBFundingCycle memory _fundingCycle)
internal
pure
returns (bool)
{
return ((_fundingCycle.metadata >> 62) & 1) == 0;
return ((_fundingCycle.metadata >> 62) & 1) == 1;
}

function controllerMigrationAllowed(JBFundingCycle memory _fundingCycle)
internal
pure
returns (bool)
{
return ((_fundingCycle.metadata >> 63) & 1) == 0;
return ((_fundingCycle.metadata >> 63) & 1) == 1;
}

function shouldHoldFees(JBFundingCycle memory _fundingCycle) internal pure returns (bool) {
return ((_fundingCycle.metadata >> 64) & 1) == 0;
return ((_fundingCycle.metadata >> 64) & 1) == 1;
}

function shouldUseLocalBalanceForRedemptions(JBFundingCycle memory _fundingCycle)
internal
pure
returns (bool)
{
return ((_fundingCycle.metadata >> 65) & 1) == 0;
return ((_fundingCycle.metadata >> 65) & 1) == 1;
}

function useDataSourceForPay(JBFundingCycle memory _fundingCycle) internal pure returns (bool) {
return (_fundingCycle.metadata >> 66) & 1 == 0;
return (_fundingCycle.metadata >> 66) & 1 == 1;
}

function useDataSourceForRedeem(JBFundingCycle memory _fundingCycle)
internal
pure
returns (bool)
{
return (_fundingCycle.metadata >> 67) & 1 == 0;
return (_fundingCycle.metadata >> 67) & 1 == 1;
}

function dataSource(JBFundingCycle memory _fundingCycle)
Expand All @@ -102,47 +102,47 @@ library JBFundingCycleMetadataResolver {
@param _metadata The metadata to validate and pack.
@return packed The packed uint256 of all metadata params. The first 8 bytes specify the version.
@return packed The packed uint256 of all metadata params. The first 8 bits specify the version.
*/
function packFundingCycleMetadata(JBFundingCycleMetadata memory _metadata)
internal
pure
returns (uint256 packed)
{
// version 1 in the first 8 bytes.
// version 1 in the bits 0-7 (8 bits).
packed = 1;
// reserved rate in bits 8-23.
// reserved rate in bits 8-23 (16 bits).
packed |= _metadata.reservedRate << 8;
// bonding curve in bits 24-39.
// Redemption rate is a number 0-10000. Store the reverse so the most common case of 100% results in no storage needs.
// redemption rate in bits 24-39 (16 bits).
// redemption rate is a number 0-10000. Store the reverse so the most common case of 100% results in no storage needs.
packed |= (10000 - _metadata.redemptionRate) << 24;
// reconfiguration bonding curve rate in bits 40-55.
// Redemption rate is a number 0-10000. Store the reverse so the most common case of 100% results in no storage needs.
packed |= (10000 - _metadata.ballotRedemptionRate) << 50;
// ballot redemption rate rate in bits 40-55 (16 bits).
// ballot redemption rate is a number 0-10000. Store the reverse so the most common case of 100% results in no storage needs.
packed |= (10000 - _metadata.ballotRedemptionRate) << 40;
// pause pay in bit 56.
packed |= (_metadata.pausePay ? 1 : 0) << 56;
if (_metadata.pausePay) packed |= 1 << 56;
// pause tap in bit 57.
packed |= (_metadata.pauseDistributions ? 1 : 0) << 57;
if (_metadata.pauseDistributions) packed |= 1 << 57;
// pause redeem in bit 58.
packed |= (_metadata.pauseRedeem ? 1 : 0) << 58;
if (_metadata.pauseRedeem) packed |= 1 << 58;
// pause mint in bit 59.
packed |= (_metadata.pauseMint ? 1 : 0) << 59;
if (_metadata.pauseMint) packed |= 1 << 59;
// pause mint in bit 60.
packed |= (_metadata.pauseBurn ? 1 : 0) << 60;
if (_metadata.pauseBurn) packed |= 1 << 60;
// pause change token in bit 61.
packed |= (_metadata.allowChangeToken ? 1 : 0) << 61;
if (_metadata.allowChangeToken) packed |= 1 << 61;
// allow terminal migration in bit 62.
packed |= (_metadata.allowTerminalMigration ? 1 : 0) << 62;
if (_metadata.allowTerminalMigration) packed |= 1 << 62;
// allow controller migration in bit 63.
packed |= (_metadata.allowControllerMigration ? 1 : 0) << 63;
if (_metadata.allowControllerMigration) packed |= 1 << 63;
// hold fees in bit 64.
packed |= (_metadata.holdFees ? 1 : 0) << 64;
if (_metadata.holdFees) packed |= 1 << 64;
// useLocalBalanceForRedemptions in bit 65.
packed |= (_metadata.useLocalBalanceForRedemptions ? 1 : 0) << 65;
if (_metadata.useLocalBalanceForRedemptions) packed |= 1 << 65;
// use pay data source in bit 66.
packed |= (_metadata.useDataSourceForPay ? 1 : 0) << 66;
if (_metadata.useDataSourceForPay) packed |= 1 << 66;
// use redeem data source in bit 67.
packed |= (_metadata.useDataSourceForRedeem ? 1 : 0) << 67;
if (_metadata.useDataSourceForRedeem) packed |= 1 << 67;
// data source address in bits 68-227.
packed |= uint160(address(_metadata.dataSource)) << 68;
}
Expand Down
88 changes: 84 additions & 4 deletions test/helpers/utils.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { BigNumber } from '@ethersproject/bignumber';
import { ethers, network } from 'hardhat';

/**
* Pack array of permission indexes into BigNumber
* @param {number[]} permissionIndexes
* @return {ethers.BigNumber}
*/
export function makePackedPermissions(permissionIndexes) {
return permissionIndexes.reduce(
(sum, i) => sum.add(ethers.BigNumber.from(2).pow(i)),
ethers.BigNumber.from(0),
);
}

/**
* Create a test account
* @param {string} address
* @param {ethers.BigNumber} balance
* @return {ethers.JsonRpcSigner}
*/
export async function impersonateAccount(
address,
balance = BigNumber.from('0x1000000000000000000000'),
Expand All @@ -22,23 +33,92 @@ export async function impersonateAccount(
return await ethers.getSigner(address);
}

/**
* Deploy a test JBToken contract
* @param {string} name
* @param {string} symbol
* @return {ethers.Contract}
*/
export async function deployJbToken(name, symbol) {
const jbTokenFactory = await ethers.getContractFactory('JBToken');
return await jbTokenFactory.deploy(name, symbol);
}

/**
* Get a new date by adding days to now
* @param {number} days
* @return {date}
*/
export function daysFromNow(days) {
let date = new Date();
date.setDate(date.getDate() + days);
return date;
}


/**
* Get a new date by adding days to the original date
* @param {date} date
* @param {number} days
* @return {date}
*/
export function daysFromDate(date, days) {
let newDate = new Date();
newDate.setDate(date.getDate() + days)
newDate.setDate(date.getDate() + days);
return newDate;
}


/**
* Get date in seconds
* @param {date} date
* @return {number}
*/
export function dateInSeconds(date) {
return Math.floor(date.getTime() / 1000);
}
}

/**
* Returns a mock FundingCyleMetadata packed into a BigNumber
* @summary Should mirror the bit logic in JBFundingCycleMetadataResolver.sol.
* @param {custom obj} e.g. packFundingCycleMetadata({ reservedRate: 3500, pausePay: 1 })
* @return {ethers.BigNumber}
* @note Passing in an empty obj will use default values below
*/
export function packFundingCycleMetadata({
version = 1,
reservedRate = 0, // percentage
redemptionRate = 10000, // percentage
ballotRedemptionRate = 10000, // percentage
pausePay = 0, // boolean
pauseDistributions = 0, // boolean
pauseRedeem = 0, // boolean
pauseMint = 0, // boolean
pauseBurn = 0, // boolean
allowChangeToken = 0, // boolean
allowTerminalMigration = 0, // boolean
allowControllerMigration = 0, // boolean
holdFees = 0, // boolean
useLocalBalanceForRedemptions = 0, // boolean
useDataSourceForPay = 0, // boolean
useDataSourceForRedeem = 0, // boolean
dataSource = 0, // address
} = {}) {
const one = ethers.BigNumber.from(1);

let packed = ethers.BigNumber.from(version);
packed = packed.or(ethers.BigNumber.from(reservedRate).shl(8));
packed = packed.or(ethers.BigNumber.from(10000 - redemptionRate).shl(24));
packed = packed.or(ethers.BigNumber.from(10000 - ballotRedemptionRate).shl(40));
if (pausePay) packed = packed.or(one.shl(56));
if (pauseDistributions) packed = packed.or(one.shl(57));
if (pauseRedeem) packed = packed.or(one.shl(58));
if (pauseMint) packed = packed.or(one.shl(59));
if (pauseBurn) packed = packed.or(one.shl(60));
if (allowChangeToken) packed = packed.or(one.shl(61));
if (allowTerminalMigration) packed = packed.or(one.shl(62));
if (allowControllerMigration) packed = packed.or(one.shl(63));
if (holdFees) packed = packed.or(one.shl(64));
if (useLocalBalanceForRedemptions) packed = packed.or(one.shl(65));
if (useDataSourceForPay) packed = packed.or(one.shl(66));
if (useDataSourceForRedeem) packed = packed.or(one.shl(67));
return packed.or(ethers.BigNumber.from(dataSource).shl(68));
}

0 comments on commit e065870

Please sign in to comment.