Skip to content

Commit

Permalink
Scribe LST extension (#33)
Browse files Browse the repository at this point in the history
Co-authored-by: jar-o <jar@example.com>
  • Loading branch information
jar-o and jar-o authored Feb 22, 2024
1 parent ca7eb54 commit 23d931c
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 25 deletions.
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();
}
}

0 comments on commit 23d931c

Please sign in to comment.