Skip to content

[draft] Add OBTC #2508

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
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
25 changes: 25 additions & 0 deletions contracts/contracts/proxies/OBTCProxies.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import { InitializeGovernedUpgradeabilityProxy } from "./InitializeGovernedUpgradeabilityProxy.sol";

/**
* @notice OBTCProxy delegates calls to an OBTC implementation
*/
contract OBTCProxy is InitializeGovernedUpgradeabilityProxy {

}

/**
* @notice WrappedOBTCProxy delegates calls to a WrappedOBTC implementation
*/
contract WOBTCProxy is InitializeGovernedUpgradeabilityProxy {

}

/**
* @notice OBTCVaultProxy delegates calls to a Vault implementation
*/
contract OBTCVaultProxy is InitializeGovernedUpgradeabilityProxy {

}
22 changes: 22 additions & 0 deletions contracts/contracts/token/OBTC.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import { OUSD } from "./OUSD.sol";

/**
* @title OETH Token Contract
* @author Origin Protocol Inc
*/
contract OBTC is OUSD {
function symbol() external pure override returns (string memory) {
return "OBTC";

Check warning on line 12 in contracts/contracts/token/OBTC.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/token/OBTC.sol#L11-L12

Added lines #L11 - L12 were not covered by tests
}

function name() external pure override returns (string memory) {
return "Origin Bitcoin";

Check warning on line 16 in contracts/contracts/token/OBTC.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/token/OBTC.sol#L15-L16

Added lines #L15 - L16 were not covered by tests
}

function decimals() external pure override returns (uint8) {
return 18;

Check warning on line 20 in contracts/contracts/token/OBTC.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/token/OBTC.sol#L19-L20

Added lines #L19 - L20 were not covered by tests
}
}
22 changes: 22 additions & 0 deletions contracts/contracts/token/WOBTC.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import { WOETH } from "./WOETH.sol";
import { ERC20 } from "@openzeppelin/contracts/token/ERC20/ERC20.sol";

/**
* @title Wrapped OBTC Token Contract
* @author Origin Protocol Inc
*/

contract WOBTC is WOETH {
constructor(ERC20 underlying_) WOETH(underlying_) {}

function name() public view virtual override returns (string memory) {
return "Wrapped OBTC";

Check warning on line 16 in contracts/contracts/token/WOBTC.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/token/WOBTC.sol#L15-L16

Added lines #L15 - L16 were not covered by tests
}

function symbol() public view virtual override returns (string memory) {
return "wOBTC";

Check warning on line 20 in contracts/contracts/token/WOBTC.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/token/WOBTC.sol#L19-L20

Added lines #L19 - L20 were not covered by tests
}
}
12 changes: 12 additions & 0 deletions contracts/contracts/vault/OBTCVaultAdmin.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import { OETHVaultAdmin } from "./OETHVaultAdmin.sol";

/**
* @title OBTC VaultAdmin Contract
* @author Origin Protocol Inc
*/
contract OBTCVaultAdmin is OETHVaultAdmin {
constructor(address _wbtc) OETHVaultAdmin(_wbtc) {}
}
38 changes: 38 additions & 0 deletions contracts/contracts/vault/OBTCVaultCore.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.0;

import { StableMath } from "../utils/StableMath.sol";
import { OETHVaultCore } from "./OETHVaultCore.sol";

import { SafeERC20 } from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import { IERC20 } from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import { IStrategy } from "../interfaces/IStrategy.sol";

/**
* @title OETH Base VaultCore Contract
* @author Origin Protocol Inc
*/
contract OBTCVaultCore is OETHVaultCore {
using SafeERC20 for IERC20;
using StableMath for uint256;

constructor(address _wbtc) OETHVaultCore(_wbtc) {}

// @inheritdoc OETHVaultCore
function _redeem(uint256 _amount, uint256 _minimumUnitAmount)

Check warning on line 22 in contracts/contracts/vault/OBTCVaultCore.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/vault/OBTCVaultCore.sol#L22

Added line #L22 was not covered by tests
internal
virtual
override
{
// Only Strategist or Governor can redeem using the Vault for now.
// We don't have the onlyGovernorOrStrategist modifier on VaultCore.
// Since we won't be using that modifier anywhere in the VaultCore as well,
// the check has been added inline instead of moving it to VaultStorage.
require(
msg.sender == strategistAddr || isGovernor(),
"Caller is not the Strategist or Governor"
);

super._redeem(_amount, _minimumUnitAmount);

Check warning on line 36 in contracts/contracts/vault/OBTCVaultCore.sol

View check run for this annotation

Codecov / codecov/patch

contracts/contracts/vault/OBTCVaultCore.sol#L36

Added line #L36 was not covered by tests
}
}
178 changes: 178 additions & 0 deletions contracts/deploy/mainnet/137_obtc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
const addresses = require("../../utils/addresses");
const { deploymentWithGovernanceProposal } = require("../../utils/deploy");
const { parseUnits } = require("ethers/lib/utils");

module.exports = deploymentWithGovernanceProposal(
{
deployName: "137_obtc",
forceDeploy: false,
// forceSkip: true,
deployerIsProposer: false,
// proposalId: "",
},
async ({ deployWithConfirmation, withConfirmation }) => {
const { deployerAddr, strategistAddr, timelockAddr } =
await getNamedAccounts();

const sDeployer = await ethers.getSigner(deployerAddr);

// Deploy Oracle Router
await deployWithConfirmation("OETHFixedOracle", []);
const cOracleRouter = await ethers.getContract("OETHFixedOracle");

// Deploy proxies
await deployWithConfirmation("OBTCProxy");
const cOBTCProxy = await ethers.getContract("OBTCProxy");
await deployWithConfirmation("WOBTCProxy");
const cWOBTCProxy = await ethers.getContract("WOBTCProxy");
await deployWithConfirmation("OBTCVaultProxy");
const cOBTCVaultProxy = await ethers.getContract("OBTCVaultProxy");

// Temp Dripper
const dTempDripper = await deployWithConfirmation("FixedRateDripper", [
cOBTCVaultProxy.address,
addresses.mainnet.WBTC,
]);
console.log("FixedRateDripper deployed at", dTempDripper.address);

// Deploy core contracts
const dOBTC = await deployWithConfirmation("OBTC");
const dwOBTC = await deployWithConfirmation("WOBTC", [cOBTCProxy.address]);
const dOBTCVaultCore = await deployWithConfirmation("OBTCVaultCore", [
addresses.mainnet.WBTC,
]);
const cOBTCVaultCore = await ethers.getContract("OBTCVaultCore");
const dOBTCVaultAdmin = await deployWithConfirmation("OBTCVaultAdmin", [
addresses.mainnet.WBTC,
]);

// Get contract instances
const cOBTC = await ethers.getContractAt("OBTC", cOBTCProxy.address);
const cwOBTC = await ethers.getContractAt("WOBTC", cWOBTCProxy.address);
const cOBTCVault = await ethers.getContractAt(
"IVault",
cOBTCVaultProxy.address
);

// Init OBTC
const resolution = ethers.utils.parseUnits("1", 27);
const initDataOBTC = cOBTC.interface.encodeFunctionData(
"initialize(address,uint256)",
[cOBTCVaultProxy.address, resolution]
);
// prettier-ignore
await withConfirmation(
cOBTCProxy
.connect(sDeployer)["initialize(address,address,bytes)"](
dOBTC.address,
timelockAddr,
initDataOBTC
)
);
console.log("Initialized OBTCProxy and OBTC implementation");

// Init OBTCVault
const initDataOBTCVault = cOBTCVaultCore.interface.encodeFunctionData(
"initialize(address,address)",
[cOracleRouter.address, cOBTCProxy.address]
);
// prettier-ignore
await withConfirmation(
cOBTCVaultProxy
.connect(sDeployer)["initialize(address,address,bytes)"](
dOBTCVaultCore.address,
timelockAddr,
initDataOBTCVault
)
);
console.log("Initialized OBTCVault");

// Init wOBTC
const initDatawOBTC = cwOBTC.interface.encodeFunctionData(
"initialize()",
[]
);
// prettier-ignore
await withConfirmation(
cWOBTCProxy
.connect(sDeployer)["initialize(address,address,bytes)"](
dwOBTC.address,
timelockAddr,
initDatawOBTC
)
);
console.log("Initialized wOBTC");

return {
name: "Deploy OBTC",
actions: [
{
// Set VaultCore implementation
contract: cOBTCVaultProxy,
signature: "upgradeTo(address)",
args: [dOBTCVaultCore.address],
},
{
// Set VaultAdmin implementation
contract: cOBTCVault,
signature: "setAdminImpl(address)",
args: [dOBTCVaultAdmin.address],
},
{
// Allow minting with WBTC
contract: cOBTCVault,
signature: "supportAsset(address,uint8)",
args: [addresses.mainnet.WBTC, 0],
},
{
// Unpause Capital
contract: cOBTCVault,
signature: "unpauseCapital()",
args: [],
},
{
// Set async claim delay
contract: cOBTCVault,
signature: "setWithdrawalClaimDelay(uint256)",
args: [24 * 60 * 60],
},
{
// Set rebase threshold
contract: cOBTCVault,
signature: "setRebaseThreshold(uint256)",
args: [parseUnits("0.01", 18)], // 0.01 wBTC
},
{
// Set strategist
contract: cOBTCVault,
signature: "setStrategistAddr(address)",
args: [strategistAddr],
},
{
// Set max supply diff
contract: cOBTCVault,
signature: "setMaxSupplyDiff(uint256)",
args: [parseUnits("1", 18)], // 1 wBTC
},
{
// Set dripper
contract: cOBTCVault,
signature: "setDripper(address)",
args: [dTempDripper.address],
},
{
// Set drip duration
contract: cOBTCVault,
signature: "setDripDuration(uint256)",
args: [7 * 24 * 60 * 60], // 1 week
},
{
// Set max rebase rate
contract: cOBTCVault,
signature: "setRebaseRateMax(uint256)",
args: [parseUnits("10", 18)], // 10%
},
],
};
}
);
3 changes: 3 additions & 0 deletions contracts/utils/addresses.js
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,9 @@ addresses.mainnet.passthrough.uniswap.OETH_OGN =
addresses.mainnet.passthrough.uniswap.OETH_WETH =
"0x216dEBBF25e5e67e6f5B2AD59c856Fc364478A6A";

// OBTC
addresses.mainnet.WBTC = "0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599";

// Arbitrum One
addresses.arbitrumOne = {};
addresses.arbitrumOne.WOETHProxy = "0xD8724322f44E5c58D7A815F542036fb17DbbF839";
Expand Down
Loading