Skip to content

Commit

Permalink
Merge pull request #285 from yieldprotocol/fix/require-setIlk
Browse files Browse the repository at this point in the history
fix: require that `witch.setIlk` is called before `wand.makeIlk`
  • Loading branch information
alcueca authored Sep 13, 2021
2 parents b725a02 + 82fe13a commit 819a713
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 5 deletions.
16 changes: 11 additions & 5 deletions contracts/Wand.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
pragma solidity 0.8.6;
import "@yield-protocol/vault-interfaces/ICauldronGov.sol";
import "@yield-protocol/vault-interfaces/ILadleGov.sol";
// import "@yield-protocol/vault-interfaces/IWitchGov.sol";
import "@yield-protocol/vault-interfaces/IMultiOracleGov.sol";
import "@yield-protocol/vault-interfaces/IJoinFactory.sol";
import "@yield-protocol/vault-interfaces/IJoin.sol";
Expand All @@ -12,6 +13,9 @@ import "@yield-protocol/yieldspace-interfaces/IPoolFactory.sol";
import "@yield-protocol/utils-v2/contracts/access/AccessControl.sol";
import "./constants/Constants.sol";

interface IWitchGov {
function ilks(bytes6) external view returns(bool, uint32, uint64, uint128);
}

/// @dev Ladle orchestrates contract calls throughout the Yield Protocol v2 into useful and efficient governance features.
contract Wand is AccessControl, Constants {
Expand All @@ -25,15 +29,15 @@ contract Wand is AccessControl, Constants {

ICauldronGov public cauldron;
ILadleGov public ladle;
address public witch;
IWitchGov public witch;
IPoolFactory public poolFactory;
IJoinFactory public joinFactory;
IFYTokenFactory public fyTokenFactory;

constructor (
ICauldronGov cauldron_,
ILadleGov ladle_,
address witch_,
IWitchGov witch_,
IPoolFactory poolFactory_,
IJoinFactory joinFactory_,
IFYTokenFactory fyTokenFactory_
Expand All @@ -50,7 +54,7 @@ contract Wand is AccessControl, Constants {
function point(bytes32 param, address value) external auth {
if (param == "cauldron") cauldron = ICauldronGov(value);
else if (param == "ladle") ladle = ILadleGov(value);
else if (param == "witch") witch = value;
else if (param == "witch") witch = IWitchGov(value);
else if (param == "poolFactory") poolFactory = IPoolFactory(value);
else if (param == "joinFactory") joinFactory = IJoinFactory(value);
else if (param == "fyTokenFactory") fyTokenFactory = IFYTokenFactory(value);
Expand Down Expand Up @@ -88,18 +92,20 @@ contract Wand is AccessControl, Constants {
cauldron.setLendingOracle(assetId, IOracle(address(oracle)));

AccessControl baseJoin = AccessControl(address(ladle.joins(assetId)));
baseJoin.grantRole(JOIN, witch); // Give the Witch permission to join base
baseJoin.grantRole(JOIN, address(witch)); // Give the Witch permission to join base
}

/// @dev Make an ilk asset out of a generic asset.
/// @notice `oracle` must be able to deliver a value for baseId and ilkId
function makeIlk(bytes6 baseId, bytes6 ilkId, IMultiOracleGov oracle, uint32 ratio, uint96 max, uint24 min, uint8 dec) external auth {
require (address(oracle) != address(0), "Oracle required");
(bool ilkInitialized,,,) = witch.ilks(ilkId);
require (ilkInitialized == true, "Initialize ilk in Witch");
cauldron.setSpotOracle(baseId, ilkId, IOracle(address(oracle)), ratio);
cauldron.setDebtLimits(baseId, ilkId, max, min, dec);

AccessControl ilkJoin = AccessControl(address(ladle.joins(ilkId)));
ilkJoin.grantRole(EXIT, witch); // Give the Witch permission to exit ilk
ilkJoin.grantRole(EXIT, address(witch)); // Give the Witch permission to exit ilk
}

/// @dev Add an existing series to the protocol, by deploying a FYToken, and registering it in the cauldron with the approved ilks
Expand Down
2 changes: 2 additions & 0 deletions contracts/Witch.sol
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ contract Witch is AccessControl() {
}

struct Ilk {
bool initialized; // Set to true if set, as we might want all parameters set to zero
uint32 duration; // Time that auctions take to go to minimal price and stay there.
uint64 initialOffer; // Proportion of collateral that is sold at auction start (1e18 = 100%)
uint128 dust; // Minimum collateral that must be left when buying, unless buying all
Expand Down Expand Up @@ -65,6 +66,7 @@ contract Witch is AccessControl() {
function setIlk(bytes6 ilkId, uint32 duration, uint64 initialOffer, uint128 dust) external auth {
require (initialOffer <= 1e18, "Only at or under 100%");
ilks[ilkId] = Ilk({
initialized: true,
duration: duration,
initialOffer: initialOffer,
dust: dust
Expand Down
1 change: 1 addition & 0 deletions test/081_witch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ describe('Witch', function () {
expect(await witch.setIlk(ilkId, 1, 2, 3))
.to.emit(witch, 'IlkSet')
.withArgs(ilkId, 1, 2, 3)
expect((await witch.ilks(ilkId)).initialized).to.be.true
expect((await witch.ilks(ilkId)).duration).to.equal(1)
expect((await witch.ilks(ilkId)).initialOffer).to.equal(2)
expect((await witch.ilks(ilkId)).dust).to.equal(3)
Expand Down
1 change: 1 addition & 0 deletions test/shared/fixtures.ts
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,7 @@ export class YieldEnvironment {
const base = assets.get(baseId) as ERC20Mock
const ilk = assets.get(ilkId) as ERC20Mock
await spotOracle.setSource(baseId, base.address, ilkId, ilk.address, spotSource.address)
await witch.setIlk(ilkId, 4 * 60 * 60, WAD.div(2), 0)
await wand.makeIlk(baseId, ilkId, spotOracle.address, ratio, 1000000, 1, await base.decimals())
oracles.set(ilkId, (spotOracle as unknown) as OracleMock)
}
Expand Down

0 comments on commit 819a713

Please sign in to comment.