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

Wsdt/turing twitter meta #157

Merged
merged 11 commits into from
May 9, 2022
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
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ coverage.json
*.tsbuildinfo

.idea/

.serverless/
build
dist
artifacts
Expand Down
45 changes: 29 additions & 16 deletions boba_community/turing-twitter/contracts/AuthenticatedFaucet.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@
pragma solidity ^0.8.9;

import "./interfaces/ITuringHelper.sol";
import "./WithRecover.sol";
import "@openzeppelin/contracts/utils/Strings.sol";
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/access/Ownable.sol";

contract AuthenticatedFaucet is Ownable {
using ECDSA for bytes32;

contract AuthenticatedFaucet is WithRecover {
string public apiUrl;
ITuringHelper public turingHelper;
mapping(uint256 => uint256) twitterUserLastClaim;
Expand All @@ -16,9 +19,7 @@ contract AuthenticatedFaucet is WithRecover {

event GasClaimed(uint256 authorId);

/*modifier isEligible() {
_;
}*/
mapping(address => uint256) private _nonces;

constructor(string memory apiUrl_, address turingHelper_, uint256 maxClaimsPerEpoch_, uint256 testnetETHPerClaim_) {
apiUrl = apiUrl_;
Expand All @@ -29,9 +30,15 @@ contract AuthenticatedFaucet is WithRecover {
testnetETHPerClaim = testnetETHPerClaim_;
}

/// @dev Send funds to authenticated user. OnlyOwner as sent via Signature.
function sendFundsMeta(address to_, string calldata twitterPostID_, bytes32 hashedMessage_, bytes memory signature_) external {
require(verifyMessage(hashedMessage_, signature_) == to_, "Signature faulty");
_nonces[to_] = _nonces[to_] + 1;
sendFunds(to_, twitterPostID_);
}

/// @dev Send funds to authenticated user.
/// @param twitterPostID_: Tweet ID with the assigned ID.
function sendFunds(string calldata twitterPostID_) external {
function sendFunds(address to_, string calldata twitterPostID_) public {
require(address(this).balance >= testnetETHPerClaim, "No testnet funds");
if (block.timestamp >= (lastEpochStart + 1 hours)) {
lastEpochStart = block.timestamp;
Expand All @@ -42,7 +49,7 @@ contract AuthenticatedFaucet is WithRecover {

require(amountClaimsInLastEpoch < maxClaimsPerEpoch, "Rate limit reached");

bytes memory encRequest = abi.encode(_msgSender(), twitterPostID_);
bytes memory encRequest = abi.encode(to_, twitterPostID_);

(uint256 resp, uint256 authorId, uint256 errorMsgVal) = abi.decode(turingHelper.TuringTx(apiUrl, encRequest), (uint256, uint256, uint256));
// 0 = false, 1 = true
Expand All @@ -52,16 +59,22 @@ contract AuthenticatedFaucet is WithRecover {
require((block.timestamp - twitterUserLastClaim[authorId]) > 1 days, "Cooldown");
twitterUserLastClaim[authorId] = block.timestamp;

payable(_msgSender()).transfer(testnetETHPerClaim);
payable(to_).transfer(testnetETHPerClaim);
emit GasClaimed(authorId);
}

receive() external payable {}
function getNonce(address from) public view returns (uint256) {
return _nonces[from];
}

/*function verify(bytes32 _hashedMessage, uint8 _v, bytes32 _r, bytes32 _s) private pure returns (address) {
bytes memory prefix = "\x19Ethereum Signed Message:\n32";
bytes32 prefixedHashMessage = keccak256(abi.encodePacked(prefix, _hashedMessage));
address signer = ecrecover(prefixedHashMessage, _v, _r, _s);
return signer;
}*/
function verifyMessage(bytes32 _hashedMessage, bytes memory signature) public pure returns (address) {
bytes32 signedHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hashedMessage));
return signedHash.recover(signature);
}

function withdraw() external onlyOwner {
payable(owner()).transfer(address(this).balance);
}

receive() external payable {}
}
19 changes: 0 additions & 19 deletions boba_community/turing-twitter/contracts/WithRecover.sol

This file was deleted.

10 changes: 5 additions & 5 deletions boba_community/turing-twitter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,11 @@
},
"devDependencies": {
"@eth-optimism/contracts": "^0.5.11",
"@ethersproject/address": "^5.0.11",
"@ethersproject/contracts": "^5.0.11",
"@ethersproject/networks": "^5.0.11",
"@ethersproject/providers": "^5.0.24",
"@ethersproject/solidity": "^5.0.11",
"@ethersproject/address": "^5.6.0",
"@ethersproject/contracts": "^5.6.0",
"@ethersproject/networks": "^5.6.2",
"@ethersproject/providers": "^5.6.5",
"@ethersproject/solidity": "^5.6.0",
"@nomiclabs/hardhat-ethers": "^2.0.2",
"@openzeppelin/contracts": "^4.5.0",
"@openzeppelin/contracts-upgradeable": "4.3.2",
Expand Down
76 changes: 58 additions & 18 deletions boba_community/turing-twitter/test/twitter.ts
Original file line number Diff line number Diff line change
@@ -1,24 +1,19 @@
// https://github.com/bobanetwork/boba/blob/develop/packages/boba/turing/test/005_lending.ts

import {
BigNumber,
Contract,
ContractFactory,
providers,
Wallet,
utils,
} from 'ethers'
import { getContractFactory } from '@eth-optimism/contracts'
import { ethers } from 'hardhat'
import { Contract, ContractFactory, providers, utils, Wallet } from 'ethers'
import hre, { ethers } from 'hardhat'
import chai, { expect } from 'chai'
import { solidity } from 'ethereum-waffle'
import * as request from 'request-promise-native'
import TwitterAuthenticatedFaucet from '../artifacts/contracts/AuthenticatedFaucet.sol/AuthenticatedFaucet.json'
import TuringHelperJson from '../artifacts/contracts/TuringHelper.sol/TuringHelper.json'
import L2GovernanceERC20Json from '../../../packages/contracts/artifacts/contracts/standards/L2GovernanceERC20.sol/L2GovernanceERC20.json'
import BobaTuringCreditJson from '../../../packages/contracts/artifacts/contracts/L2/predeploys/BobaTuringCredit.sol/BobaTuringCredit.json'

chai.use(solidity)
const abiDecoder = require('web3-eth-abi')
import * as request from 'request-promise-native'

const fetch = require('node-fetch')
import hre from 'hardhat'

const cfg = hre.network.config
const hPort = 1235 // Port for local HTTP server
Expand All @@ -37,18 +32,15 @@ let Factory__BobaTuringCredit: ContractFactory
let Factory__ERC20Mock: ContractFactory
let erc20Mock: Contract
let Factory__TwitterClaim: ContractFactory
let Factory__TwitterClaimMeta: ContractFactory
let twitter: Contract
let twitterMeta: Contract
let Factory__TuringHelper: ContractFactory
let turingHelper: Contract
let turingCredit: Contract
let L2BOBAToken: Contract
let addressesBOBA

import TwitterAuthenticatedFaucet from '../artifacts/contracts/AuthenticatedFaucet.sol/AuthenticatedFaucet.json'
import TuringHelperJson from '../artifacts/contracts/TuringHelper.sol/TuringHelper.json'
import L2GovernanceERC20Json from '../../../packages/contracts/artifacts/contracts/standards/L2GovernanceERC20.sol/L2GovernanceERC20.json'
import BobaTuringCreditJson from '../../../packages/contracts/artifacts/contracts/L2/predeploys/BobaTuringCredit.sol/BobaTuringCredit.json'

describe('Verify Twitter post for testnet funds', function () {
before(async () => {
Factory__TuringHelper = new ContractFactory(
Expand Down Expand Up @@ -80,7 +72,7 @@ describe('Verify Twitter post for testnet funds', function () {
const fTx = await deployerWallet.sendTransaction({
...gasOverride,
to: twitter.address,
value: ethers.utils.parseEther('0.000001')
value: ethers.utils.parseEther('0.000001'),
})
await fTx.wait()
console.log('Funded faucet..')
Expand Down Expand Up @@ -162,6 +154,7 @@ describe('Verify Twitter post for testnet funds', function () {
it('should fail without funds', async () => {
await expect(
twitter.estimateGas.sendFunds(
deployerWallet.address,
'1520370421773725698',
gasOverride
)
Expand All @@ -171,12 +164,15 @@ describe('Verify Twitter post for testnet funds', function () {
it('should fail for invalid tweet', async () => {
await expect(
twitter.estimateGas.sendFunds(
deployerWallet.address,
'8392382399393',
gasOverride
)
).to.be.reverted
})

/*
// Still works
it('should conduct basic twitter claim', async () => {
const tweetId = '1522128490211991552'
await twitter.estimateGas.sendFunds(tweetId, gasOverride)
Expand All @@ -187,12 +183,56 @@ describe('Verify Twitter post for testnet funds', function () {
)
const res = await claim.wait()
expect(res).to.be.ok
})*/

it('should conduct basic twitter claim via meta transaction', async () => {
const tweetId = '1522128490211991552'

const nonce = parseInt(
await twitter.getNonce(deployerWallet.address, gasOverride),
10
)
const [signer] = await ethers.getSigners()
const hashedMsg = ethers.utils.solidityKeccak256(
['address', 'uint'],
[signer.address, nonce]
)
const messageHashBin = ethers.utils.arrayify(hashedMsg)
const signature = await signer.signMessage(messageHashBin)

const verifiedOnChain = await twitter.verifyMessage(hashedMsg, signature)
console.log('SIG', verifiedOnChain) // await sigTest.connect(userWallet).isDataValid(timestamp, signature);

console.log('Executing meta tx (backend): ', signature, nonce)
await twitter.estimateGas.sendFundsMeta(
deployerWallet.address,
tweetId,
hashedMsg,
signature,
gasOverride
)

const execTx = await twitter.sendFundsMeta(
deployerWallet.address,
tweetId,
hashedMsg,
signature,
gasOverride
)
const res = await execTx.wait()

/*await twitter.estimateGas.sendFunds(tweetId, gasOverride)
console.log('Estimated gas')
const claim = await twitter.sendFunds(tweetId, gasOverride)
const res = await claim.wait()*/
expect(res).to.be.ok
})

it('should fail for second twitter claim', async () => {
// try to claim again
await expect(
twitter.estimateGas.sendFunds(
deployerWallet.address,
'1520370421773725698',
gasOverride
)
Expand Down
42 changes: 37 additions & 5 deletions boba_community/turing-twitter/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@
"@ethersproject/logger" "^5.6.0"
"@ethersproject/properties" "^5.6.0"

"@ethersproject/[email protected]", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.11", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.6.0":
"@ethersproject/[email protected]", "@ethersproject/address@>=5.0.0-beta.128", "@ethersproject/address@^5.0.4", "@ethersproject/address@^5.6.0":
version "5.6.0"
resolved "https://registry.yarnpkg.com/@ethersproject/address/-/address-5.6.0.tgz#13c49836d73e7885fc148ad633afad729da25012"
integrity sha512-6nvhYXjbXsHPS+30sHZ+U4VMagFC/9zAk6Gd/h3S21YW4+yfb0WfRtaAIZ4kfM4rrVwqiy284LP0GtL5HXGLxQ==
Expand Down Expand Up @@ -282,7 +282,7 @@
dependencies:
"@ethersproject/bignumber" "^5.6.0"

"@ethersproject/[email protected]", "@ethersproject/contracts@^5.0.11":
"@ethersproject/[email protected]", "@ethersproject/contracts@^5.6.0":
version "5.6.0"
resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.6.0.tgz#60f2cfc7addd99a865c6c8cfbbcec76297386067"
integrity sha512-74Ge7iqTDom0NX+mux8KbRUeJgu1eHZ3iv6utv++sLJG80FVuU9HnHeKVPfjd9s3woFhaFoQGf3B3iH/FrQmgw==
Expand Down Expand Up @@ -374,13 +374,20 @@
resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.6.0.tgz#d7db1bfcc22fd2e4ab574cba0bb6ad779a9a3e7a"
integrity sha512-BiBWllUROH9w+P21RzoxJKzqoqpkyM1pRnEKG69bulE9TSQD8SAIvTQqIMZmmCO8pUNkgLP1wndX1gKghSpBmg==

"@ethersproject/[email protected]", "@ethersproject/networks@^5.0.11", "@ethersproject/networks@^5.6.0":
"@ethersproject/[email protected]", "@ethersproject/networks@^5.6.0":
version "5.6.1"
resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.1.tgz#7a21ed1f83e86121737b16841961ec99ccf5c9c7"
integrity sha512-b2rrupf3kCTcc3jr9xOWBuHylSFtbpJf79Ga7QR98ienU2UqGimPGEsYMgbI29KHJfA5Us89XwGVmxrlxmSrMg==
dependencies:
"@ethersproject/logger" "^5.6.0"

"@ethersproject/networks@^5.6.2":
version "5.6.2"
resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.6.2.tgz#2bacda62102c0b1fcee408315f2bed4f6fbdf336"
integrity sha512-9uEzaJY7j5wpYGTojGp8U89mSsgQLc40PCMJLMCnFXTs7nhBveZ0t7dbqWUNrepWTszDbFkYD6WlL8DKx5huHA==
dependencies:
"@ethersproject/logger" "^5.6.0"

"@ethersproject/[email protected]", "@ethersproject/pbkdf2@^5.6.0":
version "5.6.0"
resolved "https://registry.yarnpkg.com/@ethersproject/pbkdf2/-/pbkdf2-5.6.0.tgz#04fcc2d7c6bff88393f5b4237d906a192426685a"
Expand All @@ -396,7 +403,7 @@
dependencies:
"@ethersproject/logger" "^5.6.0"

"@ethersproject/[email protected]", "@ethersproject/providers@^5.0.24", "@ethersproject/providers@^5.5.3":
"@ethersproject/[email protected]", "@ethersproject/providers@^5.5.3":
version "5.6.2"
resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.2.tgz#b9807b1c8c6f59fa2ee4b3cf6519724d07a9f422"
integrity sha512-6/EaFW/hNWz+224FXwl8+HdMRzVHt8DpPmu5MZaIQqx/K/ELnC9eY236SMV7mleCM3NnEArFwcAAxH5kUUgaRg==
Expand All @@ -421,6 +428,31 @@
bech32 "1.1.4"
ws "7.4.6"

"@ethersproject/providers@^5.6.5":
version "5.6.5"
resolved "https://registry.yarnpkg.com/@ethersproject/providers/-/providers-5.6.5.tgz#aefecf78459817a323452e05a16d56afcf807e27"
integrity sha512-TRS+c2Ud+cMpWodmGAc9xbnYRPWzRNYt2zkCSnj58nJoamBQ6x4cUbBeo0lTC3y+6RDVIBeJv18OqsDbSktLVg==
dependencies:
"@ethersproject/abstract-provider" "^5.6.0"
"@ethersproject/abstract-signer" "^5.6.0"
"@ethersproject/address" "^5.6.0"
"@ethersproject/basex" "^5.6.0"
"@ethersproject/bignumber" "^5.6.0"
"@ethersproject/bytes" "^5.6.0"
"@ethersproject/constants" "^5.6.0"
"@ethersproject/hash" "^5.6.0"
"@ethersproject/logger" "^5.6.0"
"@ethersproject/networks" "^5.6.0"
"@ethersproject/properties" "^5.6.0"
"@ethersproject/random" "^5.6.0"
"@ethersproject/rlp" "^5.6.0"
"@ethersproject/sha2" "^5.6.0"
"@ethersproject/strings" "^5.6.0"
"@ethersproject/transactions" "^5.6.0"
"@ethersproject/web" "^5.6.0"
bech32 "1.1.4"
ws "7.4.6"

"@ethersproject/[email protected]", "@ethersproject/random@^5.6.0":
version "5.6.0"
resolved "https://registry.yarnpkg.com/@ethersproject/random/-/random-5.6.0.tgz#1505d1ab6a250e0ee92f436850fa3314b2cb5ae6"
Expand Down Expand Up @@ -458,7 +490,7 @@
elliptic "6.5.4"
hash.js "1.1.7"

"@ethersproject/[email protected]", "@ethersproject/solidity@^5.0.11":
"@ethersproject/[email protected]", "@ethersproject/solidity@^5.6.0":
version "5.6.0"
resolved "https://registry.yarnpkg.com/@ethersproject/solidity/-/solidity-5.6.0.tgz#64657362a596bf7f5630bdc921c07dd78df06dc3"
integrity sha512-YwF52vTNd50kjDzqKaoNNbC/r9kMDPq3YzDWmsjFTRBcIF1y4JCQJ8gB30wsTfHbaxgxelI5BfxQSxD/PbJOww==
Expand Down
4 changes: 3 additions & 1 deletion ops_boba/api/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import {
rinkebySwapBOBAForETH,
mainnetSwapBOBAForETH,
rinkebyGetTestnetETH,
mainnetGetTestnetETH,
} from './metatransaction-api'

export { rinkebySwapBOBAForETH, mainnetSwapBOBAForETH }
export { rinkebySwapBOBAForETH, mainnetSwapBOBAForETH, rinkebyGetTestnetETH, mainnetGetTestnetETH }
Loading