Skip to content
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

Scribe LST extension #33

Merged
merged 1 commit into from
Feb 22, 2024
Merged
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
24 changes: 0 additions & 24 deletions .github/workflows/gas.yml

This file was deleted.

8 changes: 8 additions & 0 deletions src/extensions/IScribeLST.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

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

import {IRateSource} from "./external_/interfaces/IRateSource.sol";

interface IScribeLST is IScribe, IRateSource {}
8 changes: 8 additions & 0 deletions src/extensions/IScribeOptimisticLST.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

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

import {IRateSource} from "./external_/interfaces/IRateSource.sol";

interface IScribeOptimisticLST is IScribeOptimistic, IRateSource {}
38 changes: 38 additions & 0 deletions src/extensions/ScribeLST.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.16;

import {IScribeLST} from "./IScribeLST.sol";
import {IRateSource} from "./external_/interfaces/IRateSource.sol";

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

/**
* @title ScribeLST
*
* @notice Schnorr based Oracle with onchain fault resolution for Liquid
* Staking Token APRs.
*/
contract ScribeLST is IScribeLST, Scribe {
constructor(address initialAuthed_, bytes32 wat_)
Scribe(initialAuthed_, wat_)
{}

/// @inheritdoc IRateSource
/// @dev Only callable by toll'ed address.
function getAPR() external view toll returns (uint) {
// Note that function does not revert if val is zero.
return _pokeData.val;
}
}

/**
* @dev Contract overwrite to deploy contract instances with specific naming.
*
* For more info, see docs/Deployment.md.
*/
contract Chronicle_BASE_QUOTE_COUNTER is ScribeLST {
// @todo ^^^^ ^^^^^ ^^^^^^^ Adjust name of Scribe instance.
constructor(address initialAuthed, bytes32 wat_)
ScribeLST(initialAuthed, wat_)
{}
}
38 changes: 38 additions & 0 deletions src/extensions/ScribeOptimisticLST.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.16;

import {IScribeOptimisticLST} from "./IScribeOptimisticLST.sol";
import {IRateSource} from "./external_/interfaces/IRateSource.sol";

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

/**
* @title ScribeOptimisticLST
*
* @notice Schnorr based optimistic Oracle with onchain fault resolution for
* Liquid Staking Token APRs.
*/
contract ScribeOptimisticLST is IScribeOptimisticLST, ScribeOptimistic {
constructor(address initialAuthed_, bytes32 wat_)
ScribeOptimistic(initialAuthed_, wat_)
{}

/// @inheritdoc IRateSource
/// @dev Only callable by toll'ed address.
function getAPR() external view toll returns (uint) {
// Note that function does not revert if val is zero.
return _currentPokeData().val;
}
}

/**
* @dev Contract overwrite to deploy contract instances with specific naming.
*
* For more info, see docs/Deployment.md.
*/
contract Chronicle_BASE_QUOTE_COUNTER is ScribeOptimisticLST {
// @todo ^^^^ ^^^^^ ^^^^^^^ Adjust name of Scribe instance.
constructor(address initialAuthed, bytes32 wat_)
ScribeOptimisticLST(initialAuthed, wat_)
{}
}
13 changes: 13 additions & 0 deletions src/extensions/external_/interfaces/IRateSource.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// SPDX-License-Identifier: AGPL-3.0
pragma solidity >=0.8.0;

/**
* @dev Interest rate oracle interface from [Spark](https://spark.fi/).
*
* Copied from https://github.com/marsfoundation/sparklend-advanced/blob/277ea9d9ad7faf330b88198c9c6de979a2fad561/src/interfaces/IRateSource.sol.
*/
interface IRateSource {
/// @notice Returns the oracle's current APR value.
/// @return The oracle's current APR value.
function getAPR() external view returns (uint);
}
2 changes: 1 addition & 1 deletion test/IScribeOptimisticTest.sol
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ abstract contract IScribeOptimisticTest is IScribeTest {
uint newMaxChallengeReward
);

function setUp(address scribe_) internal override(IScribeTest) {
function setUp(address scribe_) internal virtual override(IScribeTest) {
super.setUp(scribe_);

opScribe = IScribeOptimistic(scribe_);
Expand Down
25 changes: 25 additions & 0 deletions test/Runner.t.sol
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ contract ScribeInvariantTest is IScribeInvariantTest {
}
}

// -- Extensions

import {ScribeLST} from "src/extensions/ScribeLST.sol";
import {IScribeLSTTest} from "./extensions/IScribeLSTTest.sol";

contract ScribeLSTest is IScribeLSTTest {
function setUp() public {
setUp(address(new ScribeLST(address(this), "ETH/USD")));
}
}

// -- Test: Optimistic Scribe --

import {ScribeOptimistic} from "src/ScribeOptimistic.sol";
Expand All @@ -39,6 +50,20 @@ contract ScribeOptimisticTest is IScribeOptimisticTest {
}
}

// -- Extensions

import {ScribeOptimisticLST} from "src/extensions/ScribeOptimisticLST.sol";
import {IScribeOptimisticLSTTest} from
"./extensions/IScribeOptimisticLSTTest.sol";

contract ScribeOptimisticLSTTest is IScribeOptimisticLSTTest {
function setUp() public {
setUp(
payable(address(new ScribeOptimisticLST(address(this), "ETH/USD")))
);
}
}

// -- Test: Libraries --

import {LibSecp256k1Test as LibSecp256k1Test_} from "./LibSecp256k1Test.sol";
Expand Down
33 changes: 33 additions & 0 deletions test/extensions/IScribeLSTTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

import {IToll} from "chronicle-std/toll/IToll.sol";

import {IScribeLST} from "src/extensions/IScribeLST.sol";

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

abstract contract IScribeLSTTest is IScribeTest {
IScribeLST private scribeLST;

function setUp(address scribe_) internal override(IScribeTest) {
super.setUp(scribe_);

scribeLST = IScribeLST(scribe_);
}

function test_getAPR_DoesNotRevertIf_ValIsZero() public {
uint val = scribeLST.getAPR();
assertEq(val, 0);
}

// -- Test: Toll Protected Functions --

function test_getAPR_isTollProtected() public {
vm.prank(address(0xbeef));
vm.expectRevert(
abi.encodeWithSelector(IToll.NotTolled.selector, address(0xbeef))
);
scribeLST.getAPR();
}
}
33 changes: 33 additions & 0 deletions test/extensions/IScribeOptimisticLSTTest.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.16;

import {IToll} from "chronicle-std/toll/IToll.sol";

import {IScribeOptimisticLST} from "src/extensions/IScribeOptimisticLST.sol";

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

abstract contract IScribeOptimisticLSTTest is IScribeOptimisticTest {
IScribeOptimisticLST private opScribeLST;

function setUp(address scribe_) internal override(IScribeOptimisticTest) {
super.setUp(scribe_);

opScribeLST = IScribeOptimisticLST(scribe_);
}

function test_getAPR_DoesNotRevertIf_ValIsZero() public {
uint val = opScribeLST.getAPR();
assertEq(val, 0);
}

// -- Test: Toll Protected Functions --

function test_getAPR_isTollProtected() public {
vm.prank(address(0xbeef));
vm.expectRevert(
abi.encodeWithSelector(IToll.NotTolled.selector, address(0xbeef))
);
opScribeLST.getAPR();
}
}