Skip to content

Commit

Permalink
added signature to Oracle
Browse files Browse the repository at this point in the history
  • Loading branch information
David405 committed May 13, 2024
1 parent 957b0b9 commit 6fb8d23
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 75 deletions.
72 changes: 66 additions & 6 deletions contracts/Oracle.sol
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
pragma solidity 0.8.20;

import "@openzeppelin/contracts/access/AccessControl.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./interfaces/BakiOracleInterface.sol";

contract BakiOracle is AccessControl, BakiOracleInterface, Ownable {
contract BakiOracle is AccessControl, BakiOracleInterface {

bytes32 public constant DATA_FEED = keccak256("DATA_FEED");

Expand All @@ -15,8 +14,10 @@ contract BakiOracle is AccessControl, BakiOracleInterface, Ownable {

string[] public zTokenList;
uint256 public collateralUSD;
address public authorizedSigner;
uint256 private nonce;

constructor (address admin, address _datafeed, address _zusd, address _zngn, address _zzar, address _zxaf) Ownable(admin) {
constructor (address admin, address _datafeed, address _zusd, address _zngn, address _zzar, address _zxaf) {
string[4] memory default_currencies = ["zusd", "zngn", "zzar", "zxaf"];
_grantRole(DATA_FEED, _datafeed);
_grantRole(DEFAULT_ADMIN_ROLE, admin);
Expand All @@ -34,6 +35,18 @@ contract BakiOracle is AccessControl, BakiOracleInterface, Ownable {
event SetZTokenUSDValue(string indexed _name, uint256 _value);
event SetZCollateralUSD(uint256 _value);

function updateAuthorizedSigner(address _newSigner) external onlyRole(DEFAULT_ADMIN_ROLE) {
authorizedSigner = _newSigner;
}

function getAuthorizedSigner() external view returns(address){
return authorizedSigner;
}

function getNonce() external view returns(uint256){
return nonce;
}

function addZToken(string calldata _name, address _address) external onlyRole(DEFAULT_ADMIN_ROLE) {

require(_address != address(0), "Address is invalid");
Expand Down Expand Up @@ -91,16 +104,20 @@ contract BakiOracle is AccessControl, BakiOracleInterface, Ownable {
return false;
}


function setZTokenUSDValue(
string calldata _name,
uint256 _value
uint256 _value,
uint256 _nonce,
bytes memory _signature
) external onlyRole(DATA_FEED) {
address zToken = getZToken(_name);

require(_value >= 1, "Invalid value");
require(recoverSigner(_value, _nonce, _signature) == authorizedSigner, "Invalid or unauthorized signature");
require(_nonce == nonce + 1,"invalid nonce");

zTokenUSDValue[zToken] = _value;
nonce = _nonce;

emit SetZTokenUSDValue(_name, _value);
}
Expand All @@ -113,14 +130,57 @@ contract BakiOracle is AccessControl, BakiOracleInterface, Ownable {
return zTokenUSDValue[zToken];
}

function setZCollateralUSD(uint256 _value) external onlyRole(DATA_FEED){
function setZCollateralUSD(uint256 _value, uint256 _nonce, bytes memory _signature) external onlyRole(DATA_FEED){

require(recoverSigner(_value, _nonce, _signature) == authorizedSigner, "Invalid or unauthorized signature");
require(_nonce == nonce + 1,"invalid nonce");

if (_value > 1000) {
collateralUSD = 1000;
} else {
collateralUSD = _value;
}
nonce = _nonce;

emit SetZCollateralUSD(_value);
}

function recoverSigner(uint256 _value, uint256 _nonce, bytes memory _signature) internal pure returns (address) {
bytes32 dataHash = keccak256(abi.encodePacked(_value, _nonce));
bytes32 messageHash = prefixed(dataHash);

// Split the signature into r, s, and v variables
(bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);

// Perform the ecrecover operation to determine the signer
return ecrecover(messageHash, v, r, s);
}

// Internal function to split a signature into r, s, and v
function splitSignature(bytes memory sig)
internal
pure
returns (bytes32 r, bytes32 s, uint8 v)
{
require(sig.length == 65, "Invalid signature length");

assembly {
// First 32 bytes, after the length prefix
r := mload(add(sig, 32))
// Second 32 bytes
s := mload(add(sig, 64))
// Final byte (first byte of the next 32 bytes)
v := byte(0, mload(add(sig, 96)))
}

if (v < 27) {
v += 27;
}
}


function prefixed(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
}

71 changes: 71 additions & 0 deletions contracts/Test.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract PriceOracle {
uint256 public currentPrice;
address private owner;
address public authorizedSigner;

event PriceUpdated(uint256 newPrice);

constructor(address _authorizedSigner) {
owner = msg.sender;
authorizedSigner = _authorizedSigner;
}

modifier onlyOwner() {
require(msg.sender == owner, "Only owner can call this.");
_;
}


function updateAuthorizedSigner(address _newSigner) public onlyOwner {
authorizedSigner = _newSigner;
}


function updatePrice(uint256 _newPrice, uint256 _nonce, bytes memory _signature) public {
require(recoverSigner(_newPrice, _nonce, _signature) == authorizedSigner, "Invalid or unauthorized signature");
currentPrice = _newPrice;
emit PriceUpdated(_newPrice);
}


function recoverSigner(uint256 _newPrice, uint256 _nonce, bytes memory _signature) internal pure returns (address) {
bytes32 dataHash = keccak256(abi.encodePacked(_newPrice, _nonce));
bytes32 messageHash = prefixed(dataHash);

// Split the signature into r, s, and v variables
(bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature);

// Perform the ecrecover operation to determine the signer
return ecrecover(messageHash, v, r, s);
}

// Internal function to split a signature into r, s, and v
function splitSignature(bytes memory sig)
internal
pure
returns (bytes32 r, bytes32 s, uint8 v)
{
require(sig.length == 65, "Invalid signature length");

assembly {
// First 32 bytes, after the length prefix
r := mload(add(sig, 32))
// Second 32 bytes
s := mload(add(sig, 64))
// Final byte (first byte of the next 32 bytes)
v := byte(0, mload(add(sig, 96)))
}

if (v < 27) {
v += 27;
}
}


function prefixed(bytes32 hash) internal pure returns (bytes32) {
return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
}
}
119 changes: 65 additions & 54 deletions contracts/abis/Oracle.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,28 +56,6 @@
"name": "AccessControlUnauthorizedAccount",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"anonymous": false,
"inputs": [
Expand All @@ -97,25 +75,6 @@
"name": "AddZToken",
"type": "event"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"anonymous": false,
"inputs": [
Expand Down Expand Up @@ -280,6 +239,19 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "authorizedSigner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
Expand Down Expand Up @@ -312,6 +284,32 @@
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getAuthorizedSigner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getNonce",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
Expand Down Expand Up @@ -426,12 +424,12 @@
},
{
"inputs": [],
"name": "owner",
"name": "nonce",
"outputs": [
{
"internalType": "address",
"internalType": "uint256",
"name": "",
"type": "address"
"type": "uint256"
}
],
"stateMutability": "view",
Expand All @@ -450,13 +448,6 @@
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
Expand Down Expand Up @@ -499,6 +490,16 @@
"internalType": "uint256",
"name": "_value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_nonce",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_signature",
"type": "bytes"
}
],
"name": "setZCollateralUSD",
Expand All @@ -517,6 +518,16 @@
"internalType": "uint256",
"name": "_value",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "_nonce",
"type": "uint256"
},
{
"internalType": "bytes",
"name": "_signature",
"type": "bytes"
}
],
"name": "setZTokenUSDValue",
Expand Down Expand Up @@ -547,11 +558,11 @@
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"name": "_newSigner",
"type": "address"
}
],
"name": "transferOwnership",
"name": "updateAuthorizedSigner",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
Expand All @@ -575,4 +586,4 @@
"stateMutability": "view",
"type": "function"
}
]
]
Loading

0 comments on commit 6fb8d23

Please sign in to comment.