mirror of
https://github.com/FlipsideCrypto/user_metrics.git
synced 2026-02-06 11:17:49 +00:00
base contracts
This commit is contained in:
parent
68ff6a064e
commit
c56b044c7e
1
apps/.gitignore
vendored
1
apps/.gitignore
vendored
@ -3,3 +3,4 @@
|
||||
.RData
|
||||
.Ruserdata
|
||||
.DS_Store
|
||||
secrets.txt
|
||||
2
apps/optimism/attestation_contracts/.gitignore
vendored
Normal file
2
apps/optimism/attestation_contracts/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
node_modules/
|
||||
.env
|
||||
@ -0,0 +1,32 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.17;
|
||||
|
||||
contract AttestationStation {
|
||||
mapping(address => mapping(address => mapping(bytes32 => bytes))) public attestations;
|
||||
|
||||
struct AttestationData {
|
||||
address about;
|
||||
bytes32 key;
|
||||
bytes val;
|
||||
}
|
||||
|
||||
event AttestationCreated(
|
||||
address indexed creator,
|
||||
address indexed about,
|
||||
bytes32 indexed key,
|
||||
bytes val
|
||||
);
|
||||
|
||||
function attest(AttestationData[] memory _attestations) public {
|
||||
for (uint256 i = 0; i < _attestations.length; ++i) {
|
||||
AttestationData memory attestation = _attestations[i];
|
||||
attestations[msg.sender][attestation.about][attestation.key] = attestation.val;
|
||||
emit AttestationCreated(
|
||||
msg.sender,
|
||||
attestation.about,
|
||||
attestation.key,
|
||||
attestation.val
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,20 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.17;
|
||||
|
||||
interface IAttestationStation {
|
||||
struct AttestationData {
|
||||
address about;
|
||||
bytes32 key;
|
||||
bytes val;
|
||||
}
|
||||
|
||||
event AttestationCreated(
|
||||
address indexed creator,
|
||||
address indexed about,
|
||||
bytes32 indexed key,
|
||||
bytes val
|
||||
);
|
||||
|
||||
function attest(AttestationData[] memory _attestations)
|
||||
external;
|
||||
}
|
||||
@ -0,0 +1,112 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity 0.8.17;
|
||||
|
||||
import { IAttestationStation } from "./AttestationStation/IAttestationStation.sol";
|
||||
import { ECDSA } from "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
|
||||
|
||||
contract FlipsideAttestation {
|
||||
using ECDSA for bytes32;
|
||||
|
||||
/// @dev The address used to sign attestations and manage the contract.
|
||||
address public signer;
|
||||
|
||||
/// @dev The interface for OP's Attestation Station.
|
||||
IAttestationStation public attestationStation;
|
||||
|
||||
constructor(
|
||||
address _signer
|
||||
, address _attestationStation
|
||||
) {
|
||||
signer = _signer;
|
||||
attestationStation = IAttestationStation(_attestationStation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Allows the signer to change the AttestationStation implementation.
|
||||
* @param _attestationStation The address of the new AttestationStation implementation.
|
||||
*
|
||||
* Requirements:
|
||||
* - The caller must be the current signer.
|
||||
*/
|
||||
function setAttestationStation(address _attestationStation) public {
|
||||
require(msg.sender == signer, "FlipsideAttestation: Only signer can set OP AttestationStation");
|
||||
attestationStation = IAttestationStation(_attestationStation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Allows the signer to transfer signer privilege to another address.
|
||||
* @param _signer The address of the new signer.
|
||||
*
|
||||
* Requirements:
|
||||
* - The caller must be the current signer.
|
||||
*/
|
||||
function setSigner(address _signer) public {
|
||||
require(msg.sender == signer, "FlipsideAttestation: Only signer can change signer");
|
||||
signer = _signer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Verifies the attestation data before calling the OP AttestationStation attest.
|
||||
* @param _about The address of the account to be attested.
|
||||
* @param _key The key of the attestation.
|
||||
* @param _val The value of the attestation.
|
||||
* @param _signature The signature of the attestation.
|
||||
*
|
||||
* Requirements:
|
||||
* - The caller must be the current signer.
|
||||
*/
|
||||
function attest(
|
||||
address _about
|
||||
, bytes32 _key
|
||||
, bytes memory _val
|
||||
, bytes memory _signature
|
||||
)
|
||||
public
|
||||
{
|
||||
_verifySignature(
|
||||
_about
|
||||
, _key
|
||||
, _val
|
||||
, _signature
|
||||
);
|
||||
|
||||
// Send the attestation to the Attestation Station.
|
||||
IAttestationStation.AttestationData[] memory attestations = new IAttestationStation.AttestationData[](1);
|
||||
attestations[0] = IAttestationStation.AttestationData({
|
||||
about: _about
|
||||
, key: _key
|
||||
, val: _val
|
||||
});
|
||||
attestationStation.attest(attestations);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Allows the signer to change the AttestationStation implementation.
|
||||
* @param _about The address of the account to be attested.
|
||||
* @param _key The key of the attestation.
|
||||
* @param _val The value of the attestation.
|
||||
* @param _signature The signer's signed message of the attestation.
|
||||
*
|
||||
* Requirements:
|
||||
* - The signature must resolve to the signer.
|
||||
*/
|
||||
function _verifySignature(
|
||||
address _about
|
||||
, bytes32 _key
|
||||
, bytes memory _val
|
||||
, bytes memory _signature
|
||||
)
|
||||
internal
|
||||
view
|
||||
{
|
||||
bytes32 messageHash = keccak256(
|
||||
abi.encodePacked(
|
||||
_about
|
||||
, _key
|
||||
, _val
|
||||
)
|
||||
);
|
||||
|
||||
require(messageHash.toEthSignedHash().recover(_signature) == signer, "FlipsideAttestation: Invalid signature");
|
||||
}
|
||||
}
|
||||
4
apps/optimism/attestation_contracts/example.env
Normal file
4
apps/optimism/attestation_contracts/example.env
Normal file
@ -0,0 +1,4 @@
|
||||
OPTIMISM_EXPLORER_API_KEY=""
|
||||
COINMARKETCAP_API_KEY=""
|
||||
ALCHEMY_API_KEY=""
|
||||
PRIVATE_KEY=""
|
||||
132
apps/optimism/attestation_contracts/hardhat.config.js
Normal file
132
apps/optimism/attestation_contracts/hardhat.config.js
Normal file
@ -0,0 +1,132 @@
|
||||
require("hardhat-gas-reporter");
|
||||
require('hardhat-deploy');
|
||||
require("hardhat-watcher");
|
||||
require("hardhat-tracer");
|
||||
require("hardhat-abi-exporter");
|
||||
require("hardhat-api-builder");
|
||||
require("hardhat-docgen");
|
||||
require("@nomiclabs/hardhat-waffle");
|
||||
require("@nomiclabs/hardhat-etherscan");
|
||||
require('solidity-coverage');
|
||||
require("dotenv").config();
|
||||
|
||||
task("deploy", "Deploys the protocol")
|
||||
.addFlag("verify", "Verify the deployed contracts on Etherscan")
|
||||
.addParam("signerAddress", "The address of the account that will sign the attestations")
|
||||
.addParam("attestationImplementation", "The address of the attestation implementation contract")
|
||||
.setAction(async (taskArgs, hre) => {
|
||||
// Compiling all of the contracts again just in case
|
||||
await hre.run('compile');
|
||||
|
||||
const [deployer] = await ethers.getSigners();
|
||||
console.log(`✅ Connected to ${deployer.address}`);
|
||||
|
||||
const chainId = await getChainId()
|
||||
|
||||
let attestationImplementation = taskArgs.attestationImplementation;
|
||||
// Deploy a mock attestation implementation if none is provided
|
||||
if (attestationImplementation === undefined) {
|
||||
const AttestationStation = await hre.ethers.getContractFactory("Attestation");
|
||||
opAtt = await AttestationStation.deploy();
|
||||
opAtt = await AttStat.deployed();
|
||||
attestationImplementation = attestationImplementationContractDeployed.address;
|
||||
console.log("✅ Mock Attestation Station Deployed.");
|
||||
}
|
||||
|
||||
// Deploying the FlipsideAttestation router
|
||||
const FlipsideAttestation = await ethers.getContractFactory("FlipsideAttestation");
|
||||
flipAtt = await FlipsideAttestation.deploy(
|
||||
taskArgs.signerAddress,
|
||||
attestationImplementation,
|
||||
);
|
||||
flipAtt = await flipAtt.deployed();
|
||||
console.log("✅ Flipside Attestation Deployed.");
|
||||
|
||||
flipAttDeployment = {
|
||||
"Chain ID": chainId,
|
||||
"Deployer": deployer.address,
|
||||
"Flipside Attestation Address": flipAtt.address,
|
||||
"Remaining ETH Balance": parseInt((await deployer.getBalance()).toString()) / 1000000000000000000,
|
||||
}
|
||||
console.table(flipAttDeployment)
|
||||
|
||||
// Verifying
|
||||
if (taskArgs.verify !== false && chainId != '31337') {
|
||||
|
||||
// Give time for etherscan to confirm the contract before verifying.
|
||||
await new Promise(r => setTimeout(r, 30000));
|
||||
await hre.run("verify:verify", {
|
||||
address: flipAtt.address,
|
||||
constructorArguments: [
|
||||
taskArgs.signerAddress,
|
||||
attestationImplementation
|
||||
],
|
||||
});
|
||||
console.log("✅ Flipside Attestation Verified.")
|
||||
}
|
||||
});
|
||||
|
||||
module.exports = {
|
||||
solidity: {
|
||||
compilers: [
|
||||
{
|
||||
version: "0.8.17",
|
||||
settings: {
|
||||
optimizer: { // Keeps the amount of gas used in check
|
||||
enabled: true,
|
||||
runs: 1000
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
},
|
||||
gasReporter: {
|
||||
currency: 'USD',
|
||||
gasPrice: 20,
|
||||
coinmarketcap: process.env.COINMARKETCAP_API_KEY,
|
||||
showMethodSig: true,
|
||||
showTimeSpent: true,
|
||||
},
|
||||
watcher: {
|
||||
compilation: {
|
||||
tasks: ["compile"],
|
||||
files: ["./contracts"],
|
||||
verbose: true,
|
||||
},
|
||||
ci: {
|
||||
tasks: ["clean", { command: "compile", params: { quiet: true } }, { command: "test", params: { noCompile: true, testFiles: ["testfile.ts"] } }],
|
||||
}
|
||||
},
|
||||
abiExporter: {
|
||||
path: 'abis/',
|
||||
runOnCompile: true,
|
||||
clear: true,
|
||||
flat: true,
|
||||
spacing: 2,
|
||||
format: "minimal"
|
||||
},
|
||||
etherscan: {
|
||||
apiKey: {
|
||||
optimism: process.env.OPTIMISM_EXPLORER_API_KEY,
|
||||
}
|
||||
},
|
||||
defaultNetwork: "hardhat",
|
||||
networks: {
|
||||
hardhat: {
|
||||
chainId: 1337,
|
||||
gas: "auto",
|
||||
gasPrice: "auto",
|
||||
saveDeployments: false,
|
||||
mining: {
|
||||
auto: false,
|
||||
order: 'fifo',
|
||||
interval: 1500,
|
||||
}
|
||||
},
|
||||
optimism: {
|
||||
url: `https://eth-goerli.g.alchemy.com/v2/${process.env.ALCHEMY_API_KEY}`,
|
||||
accounts: [`0x${process.env.PRIVATE_KEY}`],
|
||||
gasPrice: 5000000000, // 5 gwei
|
||||
},
|
||||
}
|
||||
};
|
||||
10164
apps/optimism/attestation_contracts/package-lock.json
generated
Normal file
10164
apps/optimism/attestation_contracts/package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
19
apps/optimism/attestation_contracts/package.json
Normal file
19
apps/optimism/attestation_contracts/package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "attestation_contracts",
|
||||
"version": "1.0.0",
|
||||
"description": "Contracts for OP attestation station",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"author": "@masonchain",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"ethers": "^5.7.2",
|
||||
"hardhat": "^2.12.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"@openzeppelin/contracts": "^4.8.0",
|
||||
"hardhat-gas-reporter": "^1.0.9"
|
||||
}
|
||||
}
|
||||
@ -3,5 +3,4 @@ library(shinyBS)
|
||||
library(data.table)
|
||||
|
||||
load("data.RData")
|
||||
|
||||
|
||||
signer_private_key <- readLines("secrets.txt")
|
||||
Loading…
Reference in New Issue
Block a user