Skip to content

Commit

Permalink
Save ipfs rules string instead of bytes32 (#159)
Browse files Browse the repository at this point in the history
* Test decoding of claim

* Save ipfs hash as string

* Change naming from rulesHash to rules to allow for more flexibility in format / content

* Fix outdated comment

* Undo accidental replacement

* Fix test
  • Loading branch information
ckoopmann authored Jan 11, 2024
1 parent 3fc56f4 commit f780e9c
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 53 deletions.
26 changes: 13 additions & 13 deletions contracts/adapters/OptimisticAuctionRebalanceExtensionV1.sol
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ contract OptimisticAuctionRebalanceExtensionV1 is AuctionRebalanceExtension, As
IERC20 indexed setToken,
address indexed manager,
OptimisticRebalanceParams optimisticParams,
bytes32 indexed rulesHash
string rules
);

event RebalanceProposed(
Expand All @@ -66,7 +66,7 @@ contract OptimisticAuctionRebalanceExtensionV1 is AuctionRebalanceExtension, As
event AssertedClaim(
IERC20 indexed setToken,
address indexed _assertedBy,
bytes32 indexed rulesHash,
string rules,
bytes32 _assertionId,
bytes _claimData
);
Expand Down Expand Up @@ -99,7 +99,7 @@ contract OptimisticAuctionRebalanceExtensionV1 is AuctionRebalanceExtension, As

struct ProductSettings{
OptimisticRebalanceParams optimisticParams; // OptimisticRebalanceParams struct containing optimistic rebalance parameters.
bytes32 rulesHash; // IPFS hash of the rules for the product.
string rules; // Definition of rules for the product. (including ipfs hash pointing to full rules)
}

/* ============ State Variables ============ */
Expand All @@ -111,7 +111,7 @@ contract OptimisticAuctionRebalanceExtensionV1 is AuctionRebalanceExtension, As

// Keys for assertion claim data.
bytes public constant PROPOSAL_HASH_KEY = "proposalHash";
bytes public constant RULES_KEY = "rulesIPFSHash";
bytes public constant RULES_KEY = "rules";

/* ============ Constructor ============ */

Expand Down Expand Up @@ -178,21 +178,21 @@ contract OptimisticAuctionRebalanceExtensionV1 is AuctionRebalanceExtension, As
/**
* @dev OPERATOR ONLY: sets product settings for a given set token
* @param _optimisticParams OptimisticRebalanceParams struct containing optimistic rebalance parameters.
* @param _rulesHash bytes32 containing the ipfs hash rules for the product.
* @param _rules string describing the rules of the rebalance (including IPFS hash pointing to full rules)
*/
function setProductSettings(
OptimisticRebalanceParams memory _optimisticParams,
bytes32 _rulesHash
string memory _rules
)
external
onlyOperator
{
productSettings = ProductSettings({
optimisticParams: _optimisticParams,
rulesHash: _rulesHash
rules: _rules
});

emit ProductSettingsUpdated(setToken, setToken.manager(), _optimisticParams, _rulesHash);
emit ProductSettingsUpdated(setToken, setToken.manager(), _optimisticParams, _rules);
}

/**
Expand Down Expand Up @@ -232,10 +232,10 @@ contract OptimisticAuctionRebalanceExtensionV1 is AuctionRebalanceExtension, As
_positionMultiplier
));
require(assertionIds[proposalHash] == bytes32(0), "Proposal already exists");
require(productSettings.rulesHash != bytes32(""), "Rules not set");
require(bytes(productSettings.rules).length > 0, "Rules not set");
require(address(productSettings.optimisticParams.optimisticOracleV3) != address(0), "Oracle not set");

bytes memory claim = _constructClaim(proposalHash, productSettings.rulesHash);
bytes memory claim = _constructClaim(proposalHash, productSettings.rules);
uint256 totalBond = _pullBond(productSettings.optimisticParams);

bytes32 assertionId = productSettings.optimisticParams.optimisticOracleV3.assertTruth(
Expand All @@ -254,7 +254,7 @@ contract OptimisticAuctionRebalanceExtensionV1 is AuctionRebalanceExtension, As
assertionIdToProposalHash[assertionId] = proposalHash;

emit RebalanceProposed( setToken, _quoteAsset, _oldComponents, _newComponents, _newComponentsAuctionParams, _oldComponentsAuctionParams, _rebalanceDuration, _positionMultiplier);
emit AssertedClaim(setToken, msg.sender, productSettings.rulesHash, assertionId, claim);
emit AssertedClaim(setToken, msg.sender, productSettings.rules, assertionId, claim);
}

/**
Expand Down Expand Up @@ -369,14 +369,14 @@ contract OptimisticAuctionRebalanceExtensionV1 is AuctionRebalanceExtension, As

// Constructs the claim that will be asserted at the Optimistic Oracle V3.
// @dev Inspired by the equivalent function in the OptimisticGovernor: https://github.com/UMAprotocol/protocol/blob/96cf5be32a3f57ac761f004890dd3466c63e1fa5/packages/core/contracts/optimistic-governor/implementation/OptimisticGovernor.sol#L437
function _constructClaim(bytes32 proposalHash, bytes32 rulesHash) internal pure returns (bytes memory) {
function _constructClaim(bytes32 proposalHash, string memory rules) internal pure returns (bytes memory) {
return
abi.encodePacked(
AncillaryData.appendKeyValueBytes32("", PROPOSAL_HASH_KEY, proposalHash),
",",
RULES_KEY,
":\"",
rulesHash,
rules,
"\""
);
}
Expand Down
30 changes: 11 additions & 19 deletions test/adapters/optimisticAuctionRebalanceExtensionV1.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import "module-alias/register";

import { Address, Account } from "@utils/types";
import { base58ToHexString } from "@utils/common";
import { ADDRESS_ZERO, ZERO } from "@utils/constants";
import {
BaseManager,
Expand Down Expand Up @@ -52,6 +51,8 @@ describe("OptimisticAuctionRebalanceExtensionV1", () => {
let useAssetAllowlist: boolean;
let allowedAssets: Address[];

const ipfsHash = "Qmc5gCcjYypU7y28oCALwfSvxCBskLuPKWpK4qpterKC7z";

before(async () => {
[owner, methodologist, operator] = await getAccounts();

Expand Down Expand Up @@ -305,12 +306,10 @@ describe("OptimisticAuctionRebalanceExtensionV1", () => {
});

context("when the product settings have been set", () => {
let rulesHash: Uint8Array;
let rules: string;
let bondAmount: BigNumber;
beforeEach(async () => {
rulesHash = utils.arrayify(
base58ToHexString("Qmc5gCcjYypU7y28oCALwfSvxCBskLuPKWpK4qpterKC7z"),
);
rules = ipfsHash;
bondAmount = ether(140); // 140 INDEX minimum bond
await auctionRebalanceExtension.connect(operator.wallet).setProductSettings(
{
Expand All @@ -320,7 +319,7 @@ describe("OptimisticAuctionRebalanceExtensionV1", () => {
identifier: utils.formatBytes32String(""),
optimisticOracleV3: optimisticOracleV3Mock.address,
},
rulesHash,
rules,
);
});

Expand Down Expand Up @@ -442,12 +441,7 @@ describe("OptimisticAuctionRebalanceExtensionV1", () => {
],
),
);
const firstPart = utils.toUtf8Bytes(
"proposalHash:" + proposalHash.slice(2) + ',rulesIPFSHash:"',
);
const lastPart = utils.toUtf8Bytes('"');

return utils.hexlify(utils.concat([firstPart, rulesHash, lastPart]));
return `proposalHash:${proposalHash.slice(2)},rules:"${rules}"`;
}

context("when the extension is open for rebalance", () => {
Expand Down Expand Up @@ -528,10 +522,10 @@ describe("OptimisticAuctionRebalanceExtensionV1", () => {
expect(emittedSetToken).to.eq(setToken.address);
const assertedBy = assertEvent.args._assertedBy;
expect(assertedBy).to.eq(operator.wallet.address);
const emittedRulesHash = assertEvent.args.rulesHash;
expect(emittedRulesHash).to.eq(utils.hexlify(rulesHash));
const emittedRules = assertEvent.args.rules;
expect(emittedRules).to.eq(rules);
const claim = assertEvent.args._claimData;
expect(claim).to.eq(constructClaim());
expect(utils.toUtf8String(claim)).to.eq(constructClaim());
});

context("when the same rebalance has been proposed already", () => {
Expand Down Expand Up @@ -570,7 +564,7 @@ describe("OptimisticAuctionRebalanceExtensionV1", () => {
const currentSettings = await auctionRebalanceExtension.productSettings();
await auctionRebalanceExtension.setProductSettings(
currentSettings.optimisticParams,
constants.HashZero,
"",
);
});

Expand Down Expand Up @@ -891,9 +885,7 @@ describe("OptimisticAuctionRebalanceExtensionV1", () => {
identifier: utils.formatBytes32String(""),
optimisticOracleV3: optimisticOracleV3MockUpgraded.address,
},
utils.arrayify(
base58ToHexString("Qmc5gCcjYypU7y28oCALwfSvxCBskLuPKWpK4qpterKC7z"),
),
ipfsHash,
);

const proposalHash = await auctionRebalanceExtension
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import "module-alias/register";
import { Address, Account } from "@utils/types";
import { increaseTimeAsync } from "@utils/test";
import { setBlockNumber } from "@utils/test/testingUtils";
import { base58ToHexString } from "@utils/common";
import { ONE_HOUR_IN_SECONDS, ZERO } from "@utils/constants";
import { OptimisticAuctionRebalanceExtensionV1 } from "@utils/contracts/index";
import {
Expand Down Expand Up @@ -45,6 +44,7 @@ if (process.env.INTEGRATIONTEST) {
describe("OptimisticAuctionRebalanceExtensionV1 - Integration Test dsEth", () => {
const contractAddresses = PRODUCTION_ADDRESSES;

const rules = "Rules stored on ipfs under hash: Qmc5gCcjYypU7y28oCALwfSvxCBskLuPKWpK4qpterKC7z";
const liveness = BigNumber.from(60 * 60 * 24 * 2); // 2 days
const minimumBond = ether(140); // 140 INDEX Minimum Bond

Expand Down Expand Up @@ -154,7 +154,7 @@ if (process.env.INTEGRATIONTEST) {
let identifier: string;

beforeEach(async () => {
identifier = "0x4153534552545f54525554480000000000000000000000000000000000000000"; // ASSERT_TRUTH identifier
identifier = "0x4153534552545f54525554480000000000000000000000000000000000000000"; // ASSERT_TTH identifier

productSettings = {
collateral: collateralAssetAddress,
Expand All @@ -166,10 +166,7 @@ if (process.env.INTEGRATIONTEST) {

await auctionRebalanceExtension
.connect(operator)
.setProductSettings(
productSettings,
utils.arrayify(base58ToHexString("Qmc5gCcjYypU7y28oCALwfSvxCBskLuPKWpK4qpterKC7z")),
);
.setProductSettings(productSettings, rules);
});

context("when the extension is open to rebalances", () => {
Expand Down Expand Up @@ -198,9 +195,13 @@ if (process.env.INTEGRATIONTEST) {

subjectOldComponents = await dsEth.getComponents();

subjectNewComponents = [contractAddresses.tokens.swETH, contractAddresses.tokens.ETHx];
subjectNewComponents = [
contractAddresses.tokens.swETH,
contractAddresses.tokens.ETHx,
];
subjectNewComponentsAuctionParams = [
{ // swETH: https://etherscan.io/address/0xf951E335afb289353dc249e82926178EaC7DEd78#readProxyContract#F6
{
// swETH: https://etherscan.io/address/0xf951E335afb289353dc249e82926178EaC7DEd78#readProxyContract#F6
targetUnit: "155716754710815260",
priceAdapterName: "BoundedStepwiseLinearPriceAdapter",
priceAdapterConfigData: await priceAdapter.getEncodedData(
Expand All @@ -212,7 +213,8 @@ if (process.env.INTEGRATIONTEST) {
ether(1.043),
),
},
{ // ETHx: https://etherscan.io/address/0xcf5ea1b38380f6af39068375516daf40ed70d299#readProxyContract#F5
{
// ETHx: https://etherscan.io/address/0xcf5ea1b38380f6af39068375516daf40ed70d299#readProxyContract#F5
targetUnit: "162815732702576500",
priceAdapterName: "BoundedStepwiseLinearPriceAdapter",
priceAdapterConfigData: await priceAdapter.getEncodedData(
Expand Down Expand Up @@ -287,17 +289,17 @@ if (process.env.INTEGRATIONTEST) {
.add(effectiveBond)
.toHexString();

// set operator balance to effective bond
// set operator balance to effective bond
await ethers.provider.send("hardhat_setBalance", [
await subjectCaller.getAddress(),
quantity,
]);

await getIndexTokens(await subjectCaller.getAddress(), effectiveBond);
await indexToken
.connect(subjectCaller)
.approve(auctionRebalanceExtension.address, effectiveBond);
});
await indexToken
.connect(subjectCaller)
.approve(auctionRebalanceExtension.address, effectiveBond);
});

describe("#startRebalance", () => {
async function subject(): Promise<ContractTransaction> {
Expand Down Expand Up @@ -450,7 +452,9 @@ if (process.env.INTEGRATIONTEST) {
expect(proposalHash).to.not.eq(ethers.constants.HashZero);

await getIndexTokens(await subjectCaller.getAddress(), effectiveBond);
await indexToken.connect(subjectCaller).approve(optimisticOracleV3.address, effectiveBond);
await indexToken
.connect(subjectCaller)
.approve(optimisticOracleV3.address, effectiveBond);
await optimisticOracleV3
.connect(subjectCaller)
.disputeAssertion(proposalId, owner.address);
Expand All @@ -471,9 +475,7 @@ if (process.env.INTEGRATIONTEST) {
identifier,
optimisticOracleV3: optimisticOracleV3Mock.address,
},
utils.arrayify(
base58ToHexString("Qmc5gCcjYypU7y28oCALwfSvxCBskLuPKWpK4qpterKC7z"),
),
rules,
);

const proposalHash = await auctionRebalanceExtension
Expand Down Expand Up @@ -506,9 +508,7 @@ if (process.env.INTEGRATIONTEST) {
identifier,
optimisticOracleV3: optimisticOracleV3Mock.address,
},
utils.arrayify(
base58ToHexString("Qmc5gCcjYypU7y28oCALwfSvxCBskLuPKWpK4qpterKC7z"),
),
rules,
);
const tx = await auctionRebalanceExtension
.connect(subjectCaller)
Expand Down

0 comments on commit f780e9c

Please sign in to comment.