mirror of
https://github.com/status-im/ens-usernames.git
synced 2025-02-23 23:58:16 +00:00
merge develop
This commit is contained in:
commit
b0e75e853b
3
.gitignore
vendored
3
.gitignore
vendored
@ -8,6 +8,8 @@ __pycache__/
|
||||
chains.json
|
||||
config/production/password
|
||||
config/livenet/password
|
||||
embarkArtifacts/
|
||||
embark_demo/
|
||||
|
||||
# egg-related
|
||||
viper.egg-info/
|
||||
@ -36,7 +38,6 @@ coverage.json
|
||||
# node
|
||||
node_modules/
|
||||
npm-debug.log
|
||||
package-lock.json
|
||||
|
||||
# other
|
||||
.vs/
|
||||
|
@ -1,6 +1,6 @@
|
||||
import ERC20Token from 'Embark/contracts/ERC20Token'
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar'
|
||||
import TestToken from 'Embark/contracts/TestToken'
|
||||
import ERC20Token from '../../embarkArtifacts/contracts/ERC20Token'
|
||||
import UsernameRegistrar from '../../embarkArtifacts/contracts/UsernameRegistrar'
|
||||
import TestToken from '../../embarkArtifacts/contracts/TestToken'
|
||||
|
||||
import { getDefaultAccount } from '../utils/web3Helpers'
|
||||
import { actions as accountActions } from '../reducers/accounts'
|
||||
|
@ -1,4 +1,3 @@
|
||||
import web3 from 'Embark/web3'
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Nav, MenuItem, NavDropdown } from 'react-bootstrap';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import lang from 'i18n-js';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import web3 from 'web3';
|
||||
import ENSRegistry from 'Embark/contracts/ENSRegistry';
|
||||
import UsernameRegistrar from '../../../embarkArtifacts/contracts/UsernameRegistrar';
|
||||
|
||||
import ENSRegistry from '../../../embarkArtifacts/contracts/ENSRegistry';
|
||||
import React from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import FieldGroup from '../standard/FieldGroup';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import lang from 'i18n-js';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import web3 from 'web3';
|
||||
import UsernameRegistrar from '../../../embarkArtifacts/contracts/UsernameRegistrar';
|
||||
|
||||
import React from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import FieldGroup from '../standard/FieldGroup';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import lang from 'i18n-js';
|
||||
import React, { Fragment, PureComponent } from 'react';
|
||||
import web3 from 'web3';
|
||||
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import { connect } from 'react-redux';
|
||||
import { actions as accountActions, getDefaultAccount } from '../../reducers/accounts';
|
||||
@ -8,8 +8,8 @@ import { hash } from 'eth-ens-namehash';
|
||||
import { isNil } from 'lodash';
|
||||
import Hidden from '@material-ui/core/Hidden';
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import ENSRegistry from 'Embark/contracts/ENSRegistry';
|
||||
import UsernameRegistrar from '../../../embarkArtifacts/contracts/UsernameRegistrar';
|
||||
import ENSRegistry from '../../../embarkArtifacts/contracts/ENSRegistry';
|
||||
import { Button, Field, TextInput, MobileSearch, MobileButton, Card, Info, Text } from '../../ui/components'
|
||||
import { IconCheck } from '../../ui/icons'
|
||||
import { keyFromXY } from '../../utils/ecdsa';
|
||||
@ -17,7 +17,7 @@ import EditOptions from './EditOptions';
|
||||
import ReleaseDomainAlert from './ReleaseDomain';
|
||||
import theme from '../../ui/theme'
|
||||
import { withFormik } from 'formik';
|
||||
import PublicResolver from 'Embark/contracts/PublicResolver';
|
||||
import PublicResolver from '../../../embarkArtifacts/contracts/PublicResolver';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
import RegisterSubDomain from '../ens/registerSubDomain';
|
||||
import StatusLogo from '../../ui/icons/components/StatusLogo'
|
||||
|
@ -1,7 +1,7 @@
|
||||
import lang from 'i18n-js';
|
||||
import web3 from "Embark/web3"
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import TestToken from 'Embark/contracts/TestToken';
|
||||
|
||||
import UsernameRegistrar from '../../../embarkArtifacts/contracts/UsernameRegistrar';
|
||||
import TestToken from '../../../embarkArtifacts/contracts/TestToken';
|
||||
import React, { Fragment } from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import Hidden from '@material-ui/core/Hidden';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import lang from 'i18n-js';
|
||||
import React, { Fragment } from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import UsernameRegistrar from '../../../embarkArtifacts/contracts/UsernameRegistrar';
|
||||
import web3Utils from 'web3-utils'
|
||||
import { hash } from 'eth-ens-namehash'
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import lang from 'i18n-js';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import web3 from 'web3';
|
||||
import UsernameRegistrar from '../../../embarkArtifacts/contracts/UsernameRegistrar';
|
||||
|
||||
import React from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import FieldGroup from '../standard/FieldGroup';
|
||||
|
@ -1,7 +1,7 @@
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import web3 from "Embark/web3";
|
||||
import ENSRegistry from 'Embark/contracts/ENSRegistry';
|
||||
import PublicResolver from 'Embark/contracts/PublicResolver';
|
||||
;
|
||||
import ENSRegistry from '../../../../embarkArtifacts/contracts/ENSRegistry';
|
||||
import PublicResolver from '../../../../embarkArtifacts/contracts/PublicResolver';
|
||||
|
||||
const { methods: { owner, resolver } } = ENSRegistry;
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
import lang from 'i18n-js';
|
||||
import ENSRegistry from 'Embark/contracts/ENSRegistry';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import TestToken from 'Embark/contracts/TestToken';
|
||||
import ENSRegistry from '../../embarkArtifacts/contracts/ENSRegistry';
|
||||
import UsernameRegistrar from '../../embarkArtifacts/contracts/UsernameRegistrar';
|
||||
import TestToken from '../../embarkArtifacts/contracts/TestToken';
|
||||
import React, { Fragment } from 'react';
|
||||
import AddDomain from './ens/addDomain';
|
||||
import MoveDomain from './ens/moveDomain';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import lang from 'i18n-js';
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import ERC20Token from 'Embark/contracts/ERC20Token';
|
||||
import ERC20Token from '../../embarkArtifacts/contracts/ERC20Token';
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { Form, FormGroup, FormControl, HelpBlock, Button } from 'react-bootstrap';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import React, { Fragment, PureComponent } from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import web3 from "Embark/web3"
|
||||
|
||||
import Toggle from 'react-toggle';
|
||||
import { BigNumber } from './utils'
|
||||
import "react-toggle/style.css";
|
||||
|
@ -1,10 +1,10 @@
|
||||
import lang from 'i18n-js';
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import TestToken from 'Embark/contracts/TestToken';
|
||||
import TestToken from '../../embarkArtifacts/contracts/TestToken';
|
||||
import React from 'react';
|
||||
import { Form, FormGroup, FormControl, Button } from 'react-bootstrap';
|
||||
import { connect } from 'react-redux';
|
||||
import web3 from 'web3';
|
||||
|
||||
|
||||
import ERC20TokenUI from './erc20token';
|
||||
import { actions as accountActions } from '../reducers/accounts';
|
||||
|
@ -2,13 +2,12 @@ import React from 'react';
|
||||
import 'typeface-roboto'
|
||||
import Toggle from 'react-toggle';
|
||||
import EmbarkJS from 'Embark/EmbarkJS';
|
||||
import TestToken from 'Embark/contracts/TestToken';
|
||||
import TestToken from '../embarkArtifacts/contracts/TestToken';
|
||||
import { startCase } from 'lodash';
|
||||
import UsernameRegistrar from 'Embark/contracts/UsernameRegistrar';
|
||||
import UsernameRegistrar from '../embarkArtifacts/contracts/UsernameRegistrar';
|
||||
import NameLookup from './components/ens/nameLookup';
|
||||
import AdminMode from './components/AdminMode';
|
||||
import TokenPermissions from './components/standard/TokenPermissionConnect';
|
||||
import web3 from "Embark/web3";
|
||||
import Welcome from './components/ens/welcome';
|
||||
import Hidden from '@material-ui/core/Hidden';
|
||||
import Web3Render from './components/standard/Web3Render';
|
||||
@ -30,6 +29,8 @@ const isReady = (network, environment) => {
|
||||
if (environment === 'livenet') return true
|
||||
} else if(formattedNetwork.includes('ropsten')) {
|
||||
if (environment === 'testnet') return true
|
||||
}else if(formattedNetwork.includes('private')) {
|
||||
if (environment === 'private') return true
|
||||
}
|
||||
return formattedNetwork.includes(environment.toLowerCase());
|
||||
}
|
||||
@ -70,7 +71,7 @@ class App extends React.Component {
|
||||
componentDidMount(){
|
||||
EmbarkJS.onReady((err) => {
|
||||
getNetworkType().then(network => {
|
||||
const { environment } = EmbarkJS
|
||||
const environment = network;
|
||||
this.setState({ network, environment })
|
||||
});
|
||||
});
|
||||
|
@ -1,4 +1,4 @@
|
||||
import web3 from "Embark/web3"
|
||||
|
||||
import EmbarkJS from 'Embark/EmbarkJS'
|
||||
import store from './configureStore'
|
||||
import { fetchAndDispatchSNTAllowance, fetchAndDispatchAccountsWithBalances } from '../actions/accounts'
|
||||
|
@ -1,4 +1,4 @@
|
||||
import web3 from "Embark/web3"
|
||||
|
||||
import BigNumber from 'bignumber.js';
|
||||
|
||||
// By default BigNumber's `toString` method converts to exponential notation if the value has
|
||||
|
@ -1,62 +1,46 @@
|
||||
module.exports = {
|
||||
default: {
|
||||
enabled: true,
|
||||
client: "geth"
|
||||
},
|
||||
|
||||
development: {
|
||||
enabled: true,
|
||||
networkType: "custom", // Can be: testnet, rinkeby, livenet or custom, in which case, it will use the specified networkId
|
||||
networkId: "1337", // Network id used when networkType is custom
|
||||
isDev: true, // Uses and ephemeral proof-of-authority network with a pre-funded developer account, mining enabled
|
||||
genesisBlock: "config/development/genesis.json", // Genesis block to initiate on first creation of a development node
|
||||
datadir: ".embark/development/datadir", // Data directory for the databases and keystore
|
||||
mineWhenNeeded: true, // Uses our custom script (if isDev is false) to mine only when needed
|
||||
nodiscover: true, // Disables the peer discovery mechanism (manual peer addition)
|
||||
maxpeers: 0, // Maximum number of network peers (network disabled if set to 0) (default: 25)
|
||||
rpcHost: "localhost", // HTTP-RPC server listening interface (default: "localhost")
|
||||
rpcPort: 8545, // HTTP-RPC server listening port (default: 8545)
|
||||
rpcCorsDomain: "auto", // Comma separated list of domains from which to accept cross origin requests (browser enforced)
|
||||
// When set to "auto", Embark will automatically set the cors to the address of the webserver
|
||||
proxy: true, // Proxy is used to present meaningful information about transactions
|
||||
account: {
|
||||
// "address": "", // When specified, uses that address instead of the default one for the network
|
||||
password: "config/development/password" // Password to unlock the account
|
||||
},
|
||||
targetGasLimit: 8000000, // Target gas limit sets the artificial target gas floor for the blocks to mine
|
||||
wsRPC: true, // Enable the WS-RPC server
|
||||
wsOrigins: "auto", // Origins from which to accept websockets requests
|
||||
// When set to "auto", Embark will automatically set the cors to the address of the webserver
|
||||
wsHost: "localhost", // WS-RPC server listening interface (default: "localhost")
|
||||
wsPort: 8546, // WS-RPC server listening port (default: 8546)
|
||||
simulatorMnemonic: "example exile argue silk regular smile grass bomb merge arm assist farm", // Mnemonic used by the simulator to generate a wallet
|
||||
simulatorBlocktime: 0 // Specify blockTime in seconds for automatic mining. Default is 0 and no auto-mining.
|
||||
client: 'ganache-cli',
|
||||
clientConfig: {
|
||||
miningMode: 'dev'
|
||||
}
|
||||
},
|
||||
|
||||
testnet: {
|
||||
enabled: true,
|
||||
networkType: "testnet",
|
||||
syncMode: "light",
|
||||
rpcHost: "localhost",
|
||||
rpcPort: 8545,
|
||||
rpcCorsDomain: "http://localhost:8000",
|
||||
account: {
|
||||
accounts: [
|
||||
{
|
||||
nodeAccounts: true,
|
||||
password: "config/testnet/password"
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
livenet: {
|
||||
enabled: true,
|
||||
networkType: "livenet",
|
||||
syncMode: "light",
|
||||
rpcHost: "localhost",
|
||||
rpcPort: 8545,
|
||||
rpcCorsDomain: "http://localhost:8000",
|
||||
account: {
|
||||
accounts: [
|
||||
{
|
||||
nodeAccounts: true,
|
||||
password: "config/livenet/password"
|
||||
}
|
||||
]
|
||||
},
|
||||
privatenet: {
|
||||
enabled: true,
|
||||
networkType: "custom",
|
||||
rpcHost: "localhost",
|
||||
rpcPort: 8545,
|
||||
rpcCorsDomain: "http://localhost:8000",
|
||||
datadir: "yourdatadir",
|
||||
networkId: "123",
|
||||
bootnodes: ""
|
||||
|
||||
rinkeby: {
|
||||
networkType: "rinkeby",
|
||||
syncMode: "light",
|
||||
accounts: [
|
||||
{
|
||||
nodeAccounts: true,
|
||||
password: "config/rinkeby/password"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
@ -1,12 +1,8 @@
|
||||
module.exports = {
|
||||
default: {
|
||||
enabled: true,
|
||||
provider: "whisper", // Communication provider. Currently, Embark only supports whisper
|
||||
available_providers: ["whisper"], // Array of available providers
|
||||
connection: {
|
||||
host: "localhost", // Host of the blockchain node
|
||||
port: 8546, // Port of the blockchain node
|
||||
type: "ws" // Type of connection (ws or rpc)
|
||||
}
|
||||
enabled: false,
|
||||
provider: "whisper",
|
||||
available_providers: ["whisper"],
|
||||
client: "geth"
|
||||
}
|
||||
};
|
||||
|
@ -4,31 +4,30 @@ const { ReservedUsernames } = require('./ens-usernames/reservedNames.js');
|
||||
const merkleTree = new MerkleTree(ReservedUsernames);
|
||||
|
||||
module.exports = {
|
||||
"default": {
|
||||
"deployment": {
|
||||
"host": "localhost",
|
||||
"port": 8545,
|
||||
"type": "rpc"
|
||||
},
|
||||
"dappConnection": [
|
||||
"$WEB3",
|
||||
default: {
|
||||
library: 'embarkjs',
|
||||
dappConnection: [
|
||||
"$EMBARK",
|
||||
"$WEB3", // uses pre existing web3 object if available (e.g in Mist)
|
||||
"ws://localhost:8546",
|
||||
"http://localhost:8545"
|
||||
],
|
||||
"gas": "auto",
|
||||
"contracts": {
|
||||
"TestToken": {},
|
||||
"MerkleProofWrapper": {
|
||||
"deploy": false
|
||||
gas: "auto",
|
||||
strategy: "explicit",
|
||||
deploy: {
|
||||
TestToken: {},
|
||||
MerkleProofWrapper: {
|
||||
deploy: false
|
||||
},
|
||||
"ERC20Receiver": {
|
||||
"deploy": false
|
||||
ERC20Receiver: {
|
||||
deploy: false
|
||||
},
|
||||
"ENSRegistry": {},
|
||||
"PublicResolver": {
|
||||
"args": ["$ENSRegistry"]
|
||||
ENSRegistry: {},
|
||||
PublicResolver: {
|
||||
args: ["$ENSRegistry"]
|
||||
},
|
||||
"UsernameRegistrar": {
|
||||
"args": [
|
||||
UsernameRegistrar: {
|
||||
args: [
|
||||
"$TestToken",
|
||||
"$ENSRegistry",
|
||||
"$PublicResolver",
|
||||
@ -40,87 +39,87 @@ module.exports = {
|
||||
}
|
||||
}
|
||||
},
|
||||
"development": {
|
||||
"contracts": {
|
||||
"TestToken": {
|
||||
"deploy": true
|
||||
development: {
|
||||
deploy: {
|
||||
TestToken: {
|
||||
deploy: true
|
||||
},
|
||||
"ENSRegistry": {
|
||||
"deploy": true,
|
||||
"onDeploy": [
|
||||
ENSRegistry: {
|
||||
deploy: true,
|
||||
onDeploy: [
|
||||
"ENSRegistry.methods.setSubnodeOwner('0x0000000000000000000000000000000000000000000000000000000000000000', '0x4f5b812789fc606be1b3b16908db13fc7a9adf7ca72641f84d75b47069d3d7f0', web3.eth.defaultAccount).send()"
|
||||
]
|
||||
},
|
||||
"PublicResolver": {
|
||||
"deploy": true,
|
||||
"args": [
|
||||
PublicResolver: {
|
||||
deploy: true,
|
||||
args: [
|
||||
"$ENSRegistry"
|
||||
]
|
||||
},
|
||||
"UsernameRegistrar": {
|
||||
"onDeploy": [
|
||||
UsernameRegistrar: {
|
||||
onDeploy: [
|
||||
"ENSRegistry.methods.setSubnodeOwner('0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae', '0xbd99f8d5e7f81d2d7c1da34b67a2bb3a94dd8c9b0ab40ddc077621b98405983b', UsernameRegistrar.address).send()"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"livenet":{
|
||||
"contracts": {
|
||||
"ENSRegistry": {
|
||||
"address": "0x314159265dd8dbb310642f98f50c066173c1259b"
|
||||
livenet:{
|
||||
deploy: {
|
||||
ENSRegistry: {
|
||||
address: "0x314159265dd8dbb310642f98f50c066173c1259b"
|
||||
},
|
||||
"PublicResolver": {
|
||||
"address": "0x5FfC014343cd971B7eb70732021E26C35B744cc4"
|
||||
PublicResolver: {
|
||||
address: "0x5FfC014343cd971B7eb70732021E26C35B744cc4"
|
||||
},
|
||||
"TestToken": {
|
||||
"address": "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
|
||||
TestToken: {
|
||||
address: "0x744d70fdbe2ba4cf95131626614a1763df805b9e"
|
||||
},
|
||||
"UsernameRegistrar": {
|
||||
"address": "0xDB5ac1a559b02E12F29fC0eC0e37Be8E046DEF49"
|
||||
UsernameRegistrar: {
|
||||
address: "0xDB5ac1a559b02E12F29fC0eC0e37Be8E046DEF49"
|
||||
},
|
||||
"MerkleProof": {
|
||||
"address": "0x713ED9846463235df08D92B886938651105D3940"
|
||||
MerkleProof: {
|
||||
address: "0x713ED9846463235df08D92B886938651105D3940"
|
||||
},
|
||||
"MerkleProofWrapper": {
|
||||
"address": "0x76E55E13C5891a90f7fCA2e1238a6B3463F564e2"
|
||||
MerkleProofWrapper: {
|
||||
address: "0x76E55E13C5891a90f7fCA2e1238a6B3463F564e2"
|
||||
},
|
||||
"SafeMath": {
|
||||
"address": "0xA115a57952D3337e2a1aB3Cb82bA376EEcDDc469"
|
||||
SafeMath: {
|
||||
address: "0xA115a57952D3337e2a1aB3Cb82bA376EEcDDc469"
|
||||
}
|
||||
}
|
||||
},
|
||||
"testnet":{
|
||||
"contracts": {
|
||||
"ENSRegistry": {
|
||||
"address": "0x112234455c3a32fd11230c42e7bccd4a84e02010"
|
||||
testnet:{
|
||||
deploy: {
|
||||
ENSRegistry: {
|
||||
address: "0x112234455c3a32fd11230c42e7bccd4a84e02010"
|
||||
},
|
||||
"PublicResolver": {
|
||||
"address": "0x29754bADB2640b98F6deF0f52D41418b0d2e0C51"
|
||||
PublicResolver: {
|
||||
address: "0x29754bADB2640b98F6deF0f52D41418b0d2e0C51"
|
||||
},
|
||||
"TestToken": {
|
||||
"address": "0xc55cF4B03948D7EBc8b9E8BAD92643703811d162"
|
||||
TestToken: {
|
||||
address: "0xc55cF4B03948D7EBc8b9E8BAD92643703811d162"
|
||||
},
|
||||
"SafeMath": {
|
||||
"address": "0x0F9992f7737f9ba3aceD170D4D1259cb2CEcc050"
|
||||
SafeMath: {
|
||||
address: "0x0F9992f7737f9ba3aceD170D4D1259cb2CEcc050"
|
||||
},
|
||||
"MerkleProof": {
|
||||
"address": "0x5df00E70AD165D50228DB6d8285fB6EAAc630FD7"
|
||||
MerkleProof: {
|
||||
address: "0x5df00E70AD165D50228DB6d8285fB6EAAc630FD7"
|
||||
},
|
||||
"MerkleProofWrapper": {
|
||||
"address": "0x58E01078d14142E0370526dFdAE44E4f508c844B"
|
||||
MerkleProofWrapper: {
|
||||
address: "0x58E01078d14142E0370526dFdAE44E4f508c844B"
|
||||
},
|
||||
"UsernameRegistrar": {
|
||||
"address": "0x11d9F481effd20D76cEE832559bd9Aca25405841"
|
||||
UsernameRegistrar: {
|
||||
address: "0x11d9F481effd20D76cEE832559bd9Aca25405841"
|
||||
}
|
||||
}
|
||||
},
|
||||
"rinkeby":{
|
||||
"contracts": {
|
||||
"ENSRegistry": {
|
||||
"address": "0xe7410170f87102DF0055eB195163A03B7F2Bff4A"
|
||||
rinkeby:{
|
||||
deploy: {
|
||||
ENSRegistry: {
|
||||
address: "0xe7410170f87102DF0055eB195163A03B7F2Bff4A"
|
||||
},
|
||||
"PublicResolver": {
|
||||
"address": "0x5d20cf83cb385e06d2f2a892f9322cd4933eacdc"
|
||||
PublicResolver: {
|
||||
address: "0x5d20cf83cb385e06d2f2a892f9322cd4933eacdc"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
default: {
|
||||
enabled: false,
|
||||
available_providers: ["ens"],
|
||||
provider: "ens"
|
||||
}
|
||||
|
4
config/pipeline.js
Normal file
4
config/pipeline.js
Normal file
@ -0,0 +1,4 @@
|
||||
module.exports = {
|
||||
typescript: false,
|
||||
enabled: true
|
||||
};
|
@ -2,9 +2,9 @@ module.exports = {
|
||||
default: {
|
||||
enabled: true,
|
||||
ipfs_bin: "ipfs",
|
||||
provider: "ipfs",
|
||||
available_providers: ["ipfs"],
|
||||
upload: {
|
||||
provider: "ipfs",
|
||||
host: "localhost",
|
||||
port: 5001
|
||||
},
|
||||
@ -16,20 +16,23 @@ module.exports = {
|
||||
getUrl: "http://localhost:8080/ipfs/"
|
||||
}
|
||||
]
|
||||
// Configuration to start Swarm in the same terminal as `embark run`
|
||||
/*,account: {
|
||||
address: "YOUR_ACCOUNT_ADDRESS", // Address of account accessing Swarm
|
||||
password: "PATH/TO/PASSWORD/FILE" // File containing the password of the account
|
||||
},
|
||||
swarmPath: "PATH/TO/SWARM/EXECUTABLE" // Path to swarm executable (default: swarm)*/
|
||||
},
|
||||
|
||||
development: {
|
||||
enabled: true,
|
||||
provider: "ipfs",
|
||||
upload: {
|
||||
provider: "ipfs",
|
||||
host: "localhost",
|
||||
port: 5001,
|
||||
getUrl: "http://localhost:8080/ipfs/"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
testnet: {
|
||||
},
|
||||
|
||||
livenet: {
|
||||
},
|
||||
|
||||
rinkeby: {
|
||||
},
|
||||
};
|
||||
|
@ -1,5 +1,6 @@
|
||||
module.exports = {
|
||||
enabled: true,
|
||||
host: "localhost",
|
||||
openBrowser: true,
|
||||
port: 8000
|
||||
};
|
||||
|
@ -1,14 +1,16 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
contract Controlled {
|
||||
/// @notice The address of the controller is the only address that can call
|
||||
/// a function with this modifier
|
||||
modifier onlyController {
|
||||
require(msg.sender == controller);
|
||||
require(msg.sender == controller, "Unauthorized");
|
||||
_;
|
||||
}
|
||||
|
||||
address public controller;
|
||||
address payable public controller;
|
||||
|
||||
constructor() internal {
|
||||
controller = msg.sender;
|
||||
@ -16,7 +18,7 @@ contract Controlled {
|
||||
|
||||
/// @notice Changes the controller of the contract
|
||||
/// @param _newController The new controller of the contract
|
||||
function changeController(address _newController) public onlyController {
|
||||
function changeController(address payable _newController) public onlyController {
|
||||
controller = _newController;
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
|
||||
/**
|
||||
@ -15,7 +17,7 @@ library MerkleProof {
|
||||
* @param _leaf Leaf of Merkle tree
|
||||
*/
|
||||
function verifyProof(
|
||||
bytes32[] _proof,
|
||||
bytes32[] memory _proof,
|
||||
bytes32 _root,
|
||||
bytes32 _leaf
|
||||
)
|
||||
|
@ -1,13 +1,13 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
/**
|
||||
* @notice Uses ethereum signed messages
|
||||
*/
|
||||
contract MessageSigned {
|
||||
|
||||
constructor() internal {
|
||||
|
||||
}
|
||||
constructor() internal {}
|
||||
|
||||
/**
|
||||
* @notice recovers address who signed the message
|
||||
@ -16,7 +16,7 @@ contract MessageSigned {
|
||||
*/
|
||||
function recoverAddress(
|
||||
bytes32 _signHash,
|
||||
bytes _messageSignature
|
||||
bytes memory _messageSignature
|
||||
)
|
||||
internal
|
||||
pure
|
||||
@ -42,8 +42,8 @@ contract MessageSigned {
|
||||
function getSignHash(
|
||||
bytes32 _hash
|
||||
)
|
||||
pure
|
||||
internal
|
||||
pure
|
||||
returns (bytes32 signHash)
|
||||
{
|
||||
signHash = keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash));
|
||||
@ -52,11 +52,12 @@ contract MessageSigned {
|
||||
/**
|
||||
* @dev divides bytes signature into `uint8 v, bytes32 r, bytes32 s`
|
||||
*/
|
||||
function signatureSplit(bytes _signature)
|
||||
pure
|
||||
function signatureSplit(bytes memory _signature)
|
||||
internal
|
||||
pure
|
||||
returns (uint8 v, bytes32 r, bytes32 s)
|
||||
{
|
||||
require(_signature.length == 65, "Bad signature length");
|
||||
// The signature format is a compact form of:
|
||||
// {bytes32 r}{bytes32 s}{uint8 v}
|
||||
// Compact means, uint8 is not padded to 32 bytes.
|
||||
@ -70,8 +71,10 @@ contract MessageSigned {
|
||||
// use the second best option, 'and'
|
||||
v := and(mload(add(_signature, 65)), 0xff)
|
||||
}
|
||||
|
||||
require(v == 27 || v == 28);
|
||||
if (v < 27) {
|
||||
v += 27;
|
||||
}
|
||||
require(v == 27 || v == 28, "Bad signature version");
|
||||
}
|
||||
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
/// @dev `Owned` is a base level contract that assigns an `owner` that can be
|
||||
/// later changed
|
||||
@ -7,23 +9,23 @@ contract Owned {
|
||||
/// @dev `owner` is the only address that can call a function with this
|
||||
/// modifier
|
||||
modifier onlyOwner() {
|
||||
require(msg.sender == owner);
|
||||
require(msg.sender == owner, "Unauthorized");
|
||||
_;
|
||||
}
|
||||
|
||||
address public owner;
|
||||
address payable public owner;
|
||||
|
||||
/// @notice The Constructor assigns the message sender to be `owner`
|
||||
constructor() internal {
|
||||
owner = msg.sender;
|
||||
}
|
||||
|
||||
address public newOwner;
|
||||
address payable public newOwner;
|
||||
|
||||
/// @notice `owner` can step down and assign some other address to this role
|
||||
/// @param _newOwner The address of the new owner. 0x0 can be used to create
|
||||
/// an unowned neutral vault, however that cannot be undone
|
||||
function changeOwner(address _newOwner) public onlyOwner {
|
||||
function changeOwner(address payable _newOwner) public onlyOwner {
|
||||
newOwner = _newOwner;
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
/**
|
||||
* Math operations with safety checks
|
||||
|
@ -1,4 +1,7 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
|
||||
interface ENS {
|
||||
|
||||
@ -14,13 +17,19 @@ interface ENS {
|
||||
// Logged when the TTL of a node changes
|
||||
event NewTTL(bytes32 indexed node, uint64 ttl);
|
||||
|
||||
// Logged when an operator is added or removed.
|
||||
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
|
||||
|
||||
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public;
|
||||
function setResolver(bytes32 node, address resolver) public;
|
||||
function setOwner(bytes32 node, address owner) public;
|
||||
function setTTL(bytes32 node, uint64 ttl) public;
|
||||
function owner(bytes32 node) public view returns (address);
|
||||
function resolver(bytes32 node) public view returns (address);
|
||||
function ttl(bytes32 node) public view returns (uint64);
|
||||
|
||||
function setRecord(bytes32 _node, address _owner, address _resolver, uint64 _ttl) external;
|
||||
function setSubnodeRecord(bytes32 _node, bytes32 _label, address _owner, address _resolver, uint64 _ttl) external;
|
||||
function setSubnodeOwner(bytes32 _node, bytes32 _label, address _owner) external returns(bytes32);
|
||||
function setResolver(bytes32 _node, address _resolver) external;
|
||||
function setOwner(bytes32 _node, address _owner) external;
|
||||
function setTTL(bytes32 _node, uint64 _ttl) external;
|
||||
function setApprovalForAll(address _operator, bool _approved) external;
|
||||
function owner(bytes32 _node) external view returns (address);
|
||||
function resolver(bytes32 _node) external view returns (address);
|
||||
function ttl(bytes32 _node) external view returns (uint64);
|
||||
function recordExists(bytes32 _node) external view returns (bool);
|
||||
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
|
||||
}
|
@ -1,4 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "./ENS.sol";
|
||||
|
||||
@ -6,6 +8,7 @@ import "./ENS.sol";
|
||||
* The ENS registry contract.
|
||||
*/
|
||||
contract ENSRegistry is ENS {
|
||||
|
||||
struct Record {
|
||||
address owner;
|
||||
address resolver;
|
||||
@ -13,10 +16,12 @@ contract ENSRegistry is ENS {
|
||||
}
|
||||
|
||||
mapping (bytes32 => Record) records;
|
||||
mapping (address => mapping(address => bool)) operators;
|
||||
|
||||
// Permits modifications only by the owner of the specified node.
|
||||
modifier only_owner(bytes32 node) {
|
||||
require(records[node].owner == msg.sender);
|
||||
// Permits modifications only by the _owner of the specified _node.
|
||||
modifier authorised(bytes32 _node) {
|
||||
address _owner = records[_node].owner;
|
||||
require(_owner == msg.sender || operators[_owner][msg.sender], "ENS: Not Authorized");
|
||||
_;
|
||||
}
|
||||
|
||||
@ -28,72 +33,148 @@ contract ENSRegistry is ENS {
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers ownership of a node to a new address. May only be called by the current owner of the node.
|
||||
* @param node The node to transfer ownership of.
|
||||
* @param owner The address of the new owner.
|
||||
* @dev Sets the record for a _node.
|
||||
* @param _node The _node to update.
|
||||
* @param _owner The address of the new _owner.
|
||||
* @param _resolver The address of the _resolver.
|
||||
* @param _ttl The TTL in seconds.
|
||||
*/
|
||||
function setOwner(bytes32 node, address owner) public only_owner(node) {
|
||||
emit Transfer(node, owner);
|
||||
records[node].owner = owner;
|
||||
function setRecord(bytes32 _node, address _owner, address _resolver, uint64 _ttl) external {
|
||||
setOwner(_node, _owner);
|
||||
_setResolverAndTTL(_node, _resolver, _ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Transfers ownership of a subnode keccak256(node, label) to a new address. May only be called by the owner of the parent node.
|
||||
* @param node The parent node.
|
||||
* @param label The hash of the label specifying the subnode.
|
||||
* @param owner The address of the new owner.
|
||||
* @dev Sets the record for a subnode.
|
||||
* @param _node The parent _node.
|
||||
* @param _label The hash of the _label specifying the subnode.
|
||||
* @param _owner The address of the new _owner.
|
||||
* @param _resolver The address of the _resolver.
|
||||
* @param _ttl The TTL in seconds.
|
||||
*/
|
||||
function setSubnodeOwner(bytes32 node, bytes32 label, address owner) public only_owner(node) {
|
||||
bytes32 subnode = keccak256(abi.encodePacked(node, label));
|
||||
emit NewOwner(node, label, owner);
|
||||
records[subnode].owner = owner;
|
||||
function setSubnodeRecord(bytes32 _node, bytes32 _label, address _owner, address _resolver, uint64 _ttl) external {
|
||||
bytes32 subnode = setSubnodeOwner(_node, _label, _owner);
|
||||
_setResolverAndTTL(subnode, _resolver, _ttl);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Sets the resolver address for the specified node.
|
||||
* @param node The node to update.
|
||||
* @param resolver The address of the resolver.
|
||||
* @dev Transfers ownership of a _node to a new address. May only be called by the current _owner of the _node.
|
||||
* @param _node The _node to transfer ownership of.
|
||||
* @param _owner The address of the new _owner.
|
||||
*/
|
||||
function setResolver(bytes32 node, address resolver) public only_owner(node) {
|
||||
emit NewResolver(node, resolver);
|
||||
records[node].resolver = resolver;
|
||||
function setOwner(bytes32 _node, address _owner) public authorised(_node) {
|
||||
_setOwner(_node, _owner);
|
||||
emit Transfer(_node, _owner);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Sets the TTL for the specified node.
|
||||
* @param node The node to update.
|
||||
* @param ttl The TTL in seconds.
|
||||
* @dev Transfers ownership of a subnode keccak256(_node, _label) to a new address. May only be called by the _owner of the parent _node.
|
||||
* @param _node The parent _node.
|
||||
* @param _label The hash of the _label specifying the subnode.
|
||||
* @param _owner The address of the new _owner.
|
||||
*/
|
||||
function setTTL(bytes32 node, uint64 ttl) public only_owner(node) {
|
||||
emit NewTTL(node, ttl);
|
||||
records[node].ttl = ttl;
|
||||
function setSubnodeOwner(bytes32 _node, bytes32 _label, address _owner) public authorised(_node) returns(bytes32) {
|
||||
bytes32 subnode = keccak256(abi.encodePacked(_node, _label));
|
||||
_setOwner(subnode, _owner);
|
||||
emit NewOwner(_node, _label, _owner);
|
||||
return subnode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address that owns the specified node.
|
||||
* @param node The specified node.
|
||||
* @return address of the owner.
|
||||
* @dev Sets the _resolver address for the specified _node.
|
||||
* @param _node The _node to update.
|
||||
* @param _resolver The address of the _resolver.
|
||||
*/
|
||||
function owner(bytes32 node) public view returns (address) {
|
||||
return records[node].owner;
|
||||
function setResolver(bytes32 _node, address _resolver) public authorised(_node) {
|
||||
emit NewResolver(_node, _resolver);
|
||||
records[_node].resolver = _resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the resolver for the specified node.
|
||||
* @param node The specified node.
|
||||
* @return address of the resolver.
|
||||
* @dev Sets the TTL for the specified _node.
|
||||
* @param _node The _node to update.
|
||||
* @param _ttl The TTL in seconds.
|
||||
*/
|
||||
function resolver(bytes32 node) public view returns (address) {
|
||||
return records[node].resolver;
|
||||
function setTTL(bytes32 _node, uint64 _ttl) public authorised(_node) {
|
||||
emit NewTTL(_node, _ttl);
|
||||
records[_node].ttl = _ttl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the TTL of a node, and any records associated with it.
|
||||
* @param node The specified node.
|
||||
* @return ttl of the node.
|
||||
* @dev Enable or disable approval for a third party ("_operator") to manage
|
||||
* all of `msg.sender`'s ENS records. Emits the ApprovalForAll event.
|
||||
* @param _operator Address to add to the set of authorized operators.
|
||||
* @param _approved True if the _operator is _approved, false to revoke approval.
|
||||
*/
|
||||
function ttl(bytes32 node) public view returns (uint64) {
|
||||
return records[node].ttl;
|
||||
function setApprovalForAll(address _operator, bool _approved) external {
|
||||
operators[msg.sender][_operator] = _approved;
|
||||
emit ApprovalForAll(msg.sender, _operator, _approved);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address that owns the specified _node.
|
||||
* @param _node The specified _node.
|
||||
* @return address of the _owner.
|
||||
*/
|
||||
function owner(bytes32 _node) public view returns (address) {
|
||||
address addr = records[_node].owner;
|
||||
if (addr == address(this)) {
|
||||
return address(0x0);
|
||||
}
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the address of the _resolver for the specified _node.
|
||||
* @param _node The specified _node.
|
||||
* @return address of the _resolver.
|
||||
*/
|
||||
function resolver(bytes32 _node) public view returns (address) {
|
||||
return records[_node].resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns the TTL of a _node, and any records associated with it.
|
||||
* @param _node The specified _node.
|
||||
* @return _ttl of the _node.
|
||||
*/
|
||||
function ttl(bytes32 _node) public view returns (uint64) {
|
||||
return records[_node].ttl;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Returns whether a record has been imported to the registry.
|
||||
* @param _node The specified _node.
|
||||
* @return Bool if record exists
|
||||
*/
|
||||
function recordExists(bytes32 _node) public view returns (bool) {
|
||||
return records[_node].owner != address(0x0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Query if an address is an authorized _operator for another address.
|
||||
* @param _owner The address that owns the records.
|
||||
* @param _operator The address that acts on behalf of the _owner.
|
||||
* @return True if `_operator` is an _approved _operator for `_owner`, false otherwise.
|
||||
*/
|
||||
function isApprovedForAll(address _owner, address _operator) external view returns (bool) {
|
||||
return operators[_owner][_operator];
|
||||
}
|
||||
|
||||
function _setOwner(bytes32 _node, address _owner) internal {
|
||||
records[_node].owner = _owner;
|
||||
}
|
||||
|
||||
function _setResolverAndTTL(bytes32 _node, address _resolver, uint64 _ttl) internal {
|
||||
if(_resolver != records[_node].resolver) {
|
||||
records[_node].resolver = _resolver;
|
||||
emit NewResolver(_node, _resolver);
|
||||
}
|
||||
|
||||
if(_ttl != records[_node].ttl) {
|
||||
records[_node].ttl = _ttl;
|
||||
emit NewTTL(_node, _ttl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "./ENS.sol";
|
||||
|
||||
@ -10,20 +12,20 @@ contract PublicResolver {
|
||||
|
||||
bytes4 constant INTERFACE_META_ID = 0x01ffc9a7;
|
||||
bytes4 constant ADDR_INTERFACE_ID = 0x3b3b57de;
|
||||
bytes4 constant CONTENT_INTERFACE_ID = 0xd8389dc5;
|
||||
bytes4 constant NAME_INTERFACE_ID = 0x691f3431;
|
||||
bytes4 constant ABI_INTERFACE_ID = 0x2203ab56;
|
||||
bytes4 constant PUBKEY_INTERFACE_ID = 0xc8690233;
|
||||
bytes4 constant TEXT_INTERFACE_ID = 0x59d1d43c;
|
||||
bytes4 constant MULTIHASH_INTERFACE_ID = 0xe89401a1;
|
||||
bytes4 constant CONTENTHASH_INTERFACE_ID = 0xbc1c58d1;
|
||||
bytes4 constant INTERFACE_INTERFACE_ID = bytes4(keccak256("interfaceImplementer(bytes32,bytes4)"));
|
||||
|
||||
event AddrChanged(bytes32 indexed node, address a);
|
||||
event ContentChanged(bytes32 indexed node, bytes32 hash);
|
||||
event NameChanged(bytes32 indexed node, string name);
|
||||
event ABIChanged(bytes32 indexed node, uint256 indexed contentType);
|
||||
event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);
|
||||
event TextChanged(bytes32 indexed node, string indexedKey, string key);
|
||||
event MultihashChanged(bytes32 indexed node, bytes hash);
|
||||
event ContenthashChanged(bytes32 indexed node, bytes hash);
|
||||
event InterfaceChanged(bytes32 indexed node, bytes4 indexed interfaceID, address implementer);
|
||||
|
||||
struct PublicKey {
|
||||
bytes32 x;
|
||||
@ -32,19 +34,19 @@ contract PublicResolver {
|
||||
|
||||
struct Record {
|
||||
address addr;
|
||||
bytes32 content;
|
||||
string name;
|
||||
PublicKey pubkey;
|
||||
mapping(string=>string) text;
|
||||
mapping(uint256=>bytes) abis;
|
||||
bytes multihash;
|
||||
bytes contenthash;
|
||||
mapping(bytes4=>address) interfaces;
|
||||
}
|
||||
|
||||
ENS ens;
|
||||
|
||||
mapping (bytes32 => Record) records;
|
||||
|
||||
modifier only_owner(bytes32 node) {
|
||||
modifier onlyOwner(bytes32 node) {
|
||||
require(ens.owner(node) == msg.sender);
|
||||
_;
|
||||
}
|
||||
@ -63,7 +65,7 @@ contract PublicResolver {
|
||||
* @param node The node to update.
|
||||
* @param addr The address to set.
|
||||
*/
|
||||
function setAddr(bytes32 node, address addr) public only_owner(node) {
|
||||
function setAddr(bytes32 node, address addr) external onlyOwner(node) {
|
||||
records[node].addr = addr;
|
||||
emit AddrChanged(node, addr);
|
||||
}
|
||||
@ -71,25 +73,12 @@ contract PublicResolver {
|
||||
/**
|
||||
* Sets the contenthash associated with an ENS node.
|
||||
* May only be called by the owner of that node in the ENS registry.
|
||||
* Note that this resource type is not standardized, and will likely change
|
||||
* in future to a resource type based on multihash.
|
||||
* @param node The node to update.
|
||||
* @param hash The contenthash to set
|
||||
*/
|
||||
function setContent(bytes32 node, bytes32 hash) public only_owner(node) {
|
||||
records[node].content = hash;
|
||||
emit ContentChanged(node, hash);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the multihash associated with an ENS node.
|
||||
* May only be called by the owner of that node in the ENS registry.
|
||||
* @param node The node to update.
|
||||
* @param hash The multihash to set
|
||||
*/
|
||||
function setMultihash(bytes32 node, bytes hash) public only_owner(node) {
|
||||
records[node].multihash = hash;
|
||||
emit MultihashChanged(node, hash);
|
||||
function setContenthash(bytes32 node, bytes calldata hash) external onlyOwner(node) {
|
||||
records[node].contenthash = hash;
|
||||
emit ContenthashChanged(node, hash);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,7 +87,7 @@ contract PublicResolver {
|
||||
* @param node The node to update.
|
||||
* @param name The name to set.
|
||||
*/
|
||||
function setName(bytes32 node, string name) public only_owner(node) {
|
||||
function setName(bytes32 node, string calldata name) external onlyOwner(node) {
|
||||
records[node].name = name;
|
||||
emit NameChanged(node, name);
|
||||
}
|
||||
@ -111,7 +100,7 @@ contract PublicResolver {
|
||||
* @param contentType The content type of the ABI
|
||||
* @param data The ABI data.
|
||||
*/
|
||||
function setABI(bytes32 node, uint256 contentType, bytes data) public only_owner(node) {
|
||||
function setABI(bytes32 node, uint256 contentType, bytes calldata data) external onlyOwner(node) {
|
||||
// Content types must be powers of 2
|
||||
require(((contentType - 1) & contentType) == 0);
|
||||
|
||||
@ -125,7 +114,7 @@ contract PublicResolver {
|
||||
* @param x the X coordinate of the curve point for the public key.
|
||||
* @param y the Y coordinate of the curve point for the public key.
|
||||
*/
|
||||
function setPubkey(bytes32 node, bytes32 x, bytes32 y) public only_owner(node) {
|
||||
function setPubkey(bytes32 node, bytes32 x, bytes32 y) external onlyOwner(node) {
|
||||
records[node].pubkey = PublicKey(x, y);
|
||||
emit PubkeyChanged(node, x, y);
|
||||
}
|
||||
@ -137,18 +126,30 @@ contract PublicResolver {
|
||||
* @param key The key to set.
|
||||
* @param value The text data value to set.
|
||||
*/
|
||||
function setText(bytes32 node, string key, string value) public only_owner(node) {
|
||||
function setText(bytes32 node, string calldata key, string calldata value) external onlyOwner(node) {
|
||||
records[node].text[key] = value;
|
||||
emit TextChanged(node, key, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets an interface associated with a name.
|
||||
* Setting the address to 0 restores the default behaviour of querying the contract at `addr()` for interface support.
|
||||
* @param node The node to update.
|
||||
* @param interfaceID The EIP 168 interface ID.
|
||||
* @param implementer The address of a contract that implements this interface for this node.
|
||||
*/
|
||||
function setInterface(bytes32 node, bytes4 interfaceID, address implementer) external onlyOwner(node) {
|
||||
records[node].interfaces[interfaceID] = implementer;
|
||||
emit InterfaceChanged(node, interfaceID, implementer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the text data associated with an ENS node and key.
|
||||
* @param node The ENS node to query.
|
||||
* @param key The text data key to query.
|
||||
* @return The associated text data.
|
||||
*/
|
||||
function text(bytes32 node, string key) public view returns (string) {
|
||||
function text(bytes32 node, string calldata key) external view returns (string memory) {
|
||||
return records[node].text[key];
|
||||
}
|
||||
|
||||
@ -156,9 +157,10 @@ contract PublicResolver {
|
||||
* Returns the SECP256k1 public key associated with an ENS node.
|
||||
* Defined in EIP 619.
|
||||
* @param node The ENS node to query
|
||||
* @return x, y the X and Y coordinates of the curve point for the public key.
|
||||
* @return x Pubkey x point
|
||||
* @return y Pubkey y point
|
||||
*/
|
||||
function pubkey(bytes32 node) public view returns (bytes32 x, bytes32 y) {
|
||||
function pubkey(bytes32 node) external view returns (bytes32 x, bytes32 y) {
|
||||
return (records[node].pubkey.x, records[node].pubkey.y);
|
||||
}
|
||||
|
||||
@ -170,15 +172,17 @@ contract PublicResolver {
|
||||
* @return contentType The content type of the return value
|
||||
* @return data The ABI data
|
||||
*/
|
||||
function ABI(bytes32 node, uint256 contentTypes) public view returns (uint256 contentType, bytes data) {
|
||||
function ABI(bytes32 node, uint256 contentTypes) external view returns (uint256, bytes memory) {
|
||||
Record storage record = records[node];
|
||||
for (contentType = 1; contentType <= contentTypes; contentType <<= 1) {
|
||||
|
||||
for (uint256 contentType = 1; contentType <= contentTypes; contentType <<= 1) {
|
||||
if ((contentType & contentTypes) != 0 && record.abis[contentType].length > 0) {
|
||||
data = record.abis[contentType];
|
||||
return;
|
||||
return (contentType, record.abis[contentType]);
|
||||
}
|
||||
}
|
||||
contentType = 0;
|
||||
|
||||
bytes memory empty;
|
||||
return (0, empty);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,30 +191,10 @@ contract PublicResolver {
|
||||
* @param node The ENS node to query.
|
||||
* @return The associated name.
|
||||
*/
|
||||
function name(bytes32 node) public view returns (string) {
|
||||
function name(bytes32 node) external view returns (string memory) {
|
||||
return records[node].name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the content hash associated with an ENS node.
|
||||
* Note that this resource type is not standardized, and will likely change
|
||||
* in future to a resource type based on multihash.
|
||||
* @param node The ENS node to query.
|
||||
* @return The associated content hash.
|
||||
*/
|
||||
function content(bytes32 node) public view returns (bytes32) {
|
||||
return records[node].content;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the multihash associated with an ENS node.
|
||||
* @param node The ENS node to query.
|
||||
* @return The associated multihash.
|
||||
*/
|
||||
function multihash(bytes32 node) public view returns (bytes) {
|
||||
return records[node].multihash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address associated with an ENS node.
|
||||
* @param node The ENS node to query.
|
||||
@ -220,19 +204,64 @@ contract PublicResolver {
|
||||
return records[node].addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the contenthash associated with an ENS node.
|
||||
* @param node The ENS node to query.
|
||||
* @return The associated contenthash.
|
||||
*/
|
||||
function contenthash(bytes32 node) external view returns (bytes memory) {
|
||||
return records[node].contenthash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the address of a contract that implements the specified interface for this name.
|
||||
* If an implementer has not been set for this interfaceID and name, the resolver will query
|
||||
* the contract at `addr()`. If `addr()` is set, a contract exists at that address, and that
|
||||
* contract implements EIP168 and returns `true` for the specified interfaceID, its address
|
||||
* will be returned.
|
||||
* @param node The ENS node to query.
|
||||
* @param interfaceID The EIP 168 interface ID to check for.
|
||||
* @return The address that implements this interface, or 0 if the interface is unsupported.
|
||||
*/
|
||||
function interfaceImplementer(bytes32 node, bytes4 interfaceID) external view returns (address) {
|
||||
address implementer = records[node].interfaces[interfaceID];
|
||||
if(implementer != address(0)) {
|
||||
return implementer;
|
||||
}
|
||||
|
||||
address a = addr(node);
|
||||
if(a == address(0)) {
|
||||
return address(0);
|
||||
}
|
||||
|
||||
(bool success, bytes memory returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", INTERFACE_META_ID));
|
||||
if(!success || returnData.length < 32 || returnData[31] == 0) {
|
||||
// EIP 168 not supported by target
|
||||
return address(0);
|
||||
}
|
||||
|
||||
(success, returnData) = a.staticcall(abi.encodeWithSignature("supportsInterface(bytes4)", interfaceID));
|
||||
if(!success || returnData.length < 32 || returnData[31] == 0) {
|
||||
// Specified interface not supported by target
|
||||
return address(0);
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the resolver implements the interface specified by the provided hash.
|
||||
* @param interfaceID The ID of the interface to check for.
|
||||
* @return True if the contract implements the requested interface.
|
||||
*/
|
||||
function supportsInterface(bytes4 interfaceID) public pure returns (bool) {
|
||||
function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
|
||||
return interfaceID == ADDR_INTERFACE_ID ||
|
||||
interfaceID == CONTENT_INTERFACE_ID ||
|
||||
interfaceID == NAME_INTERFACE_ID ||
|
||||
interfaceID == ABI_INTERFACE_ID ||
|
||||
interfaceID == PUBKEY_INTERFACE_ID ||
|
||||
interfaceID == TEXT_INTERFACE_ID ||
|
||||
interfaceID == MULTIHASH_INTERFACE_ID ||
|
||||
interfaceID == CONTENTHASH_INTERFACE_ID ||
|
||||
interfaceID == INTERFACE_INTERFACE_ID ||
|
||||
interfaceID == INTERFACE_META_ID;
|
||||
}
|
||||
}
|
@ -1,10 +1,46 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
contract ResolverInterface {
|
||||
function PublicResolver(address ensAddr) public;
|
||||
function setAddr(bytes32 node, address addr) public;
|
||||
function setHash(bytes32 node, bytes32 hash) public;
|
||||
function addr(bytes32 node) public view returns (address);
|
||||
function hash(bytes32 node) public view returns (bytes32);
|
||||
function supportsInterface(bytes4 interfaceID) public pure returns (bool);
|
||||
pragma solidity 0.5.11;
|
||||
pragma experimental ABIEncoderV2;
|
||||
|
||||
/**
|
||||
* A generic resolver interface which includes all the functions including the ones deprecated
|
||||
*/
|
||||
interface Resolver{
|
||||
event AddrChanged(bytes32 indexed node, address a);
|
||||
event AddressChanged(bytes32 indexed node, uint coinType, bytes newAddress);
|
||||
event NameChanged(bytes32 indexed node, string name);
|
||||
event ABIChanged(bytes32 indexed node, uint256 indexed contentType);
|
||||
event PubkeyChanged(bytes32 indexed node, bytes32 x, bytes32 y);
|
||||
event TextChanged(bytes32 indexed node, string indexed indexedKey, string key);
|
||||
event ContenthashChanged(bytes32 indexed node, bytes hash);
|
||||
/* Deprecated events */
|
||||
event ContentChanged(bytes32 indexed node, bytes32 hash);
|
||||
|
||||
function ABI(bytes32 _node, uint256 _contentTypes) external view returns (uint256, bytes memory);
|
||||
function addr(bytes32 _node) external view returns (address);
|
||||
function addr(bytes32 _node, uint _coinType) external view returns(bytes memory);
|
||||
function contenthash(bytes32 _node) external view returns (bytes memory);
|
||||
function dnsrr(bytes32 _node) external view returns (bytes memory);
|
||||
function name(bytes32 _node) external view returns (string memory);
|
||||
function pubkey(bytes32 _node) external view returns (bytes32 x, bytes32 y);
|
||||
function text(bytes32 _node, string calldata _key) external view returns (string memory);
|
||||
function interfaceImplementer(bytes32 _node, bytes4 _interfaceID) external view returns (address);
|
||||
function setABI(bytes32 _node, uint256 _contentType, bytes calldata _data) external;
|
||||
function setAddr(bytes32 _node, address _addr) external;
|
||||
function setAddr(bytes32 _node, uint _coinType, bytes calldata _a) external;
|
||||
function setContenthash(bytes32 _node, bytes calldata _hash) external;
|
||||
function setDnsrr(bytes32 _node, bytes calldata _data) external;
|
||||
function setName(bytes32 _node, string calldata _name) external;
|
||||
function setPubkey(bytes32 _node, bytes32 _x, bytes32 _y) external;
|
||||
function setText(bytes32 _node, string calldata _key, string calldata _value) external;
|
||||
function setInterface(bytes32 _node, bytes4 _interfaceID, address _implementer) external;
|
||||
function supportsInterface(bytes4 _interfaceID) external pure returns (bool);
|
||||
function multicall(bytes[] calldata _data) external returns(bytes[] memory results);
|
||||
|
||||
/* Deprecated functions */
|
||||
function content(bytes32 _node) external view returns (bytes32);
|
||||
function multihash(bytes32 _node) external view returns (bytes memory);
|
||||
function setContent(bytes32 _node, bytes32 hash) external;
|
||||
function setMultihash(bytes32 _node, bytes calldata _hash) external;
|
||||
}
|
||||
|
22
contracts/mocks/Dummy2SlashMechanism.sol
Normal file
22
contracts/mocks/Dummy2SlashMechanism.sol
Normal file
@ -0,0 +1,22 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "../registry/SlashMechanism.sol";
|
||||
|
||||
|
||||
contract Dummy2SlashMechanism is SlashMechanism {
|
||||
|
||||
constructor(
|
||||
uint256 _usernameMinLength,
|
||||
bytes32 _reservedUsernamesMerkleRoot
|
||||
)
|
||||
public
|
||||
SlashMechanism(
|
||||
_usernameMinLength,
|
||||
_reservedUsernamesMerkleRoot
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
30
contracts/mocks/Dummy2UsernameRegistrar.sol
Normal file
30
contracts/mocks/Dummy2UsernameRegistrar.sol
Normal file
@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "../registry/UsernameRegistrar.sol";
|
||||
|
||||
contract Dummy2UsernameRegistrar is UsernameRegistrar {
|
||||
|
||||
constructor(
|
||||
ERC20Token _token,
|
||||
ENS _ensRegistry,
|
||||
PublicResolver _resolver,
|
||||
bytes32 _ensNode,
|
||||
address _slashMechanism,
|
||||
address _parentRegistry
|
||||
)
|
||||
public
|
||||
UsernameRegistrar(
|
||||
_token,
|
||||
_ensRegistry,
|
||||
_resolver,
|
||||
_ensNode,
|
||||
_slashMechanism,
|
||||
_parentRegistry
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
30
contracts/mocks/DummyUsernameRegistrar.sol
Normal file
30
contracts/mocks/DummyUsernameRegistrar.sol
Normal file
@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "../registry/UsernameRegistrar.sol";
|
||||
|
||||
contract DummyUsernameRegistrar is UsernameRegistrar {
|
||||
|
||||
constructor(
|
||||
ERC20Token _token,
|
||||
ENS _ensRegistry,
|
||||
PublicResolver _resolver,
|
||||
bytes32 _ensNode,
|
||||
address _slashMechanism,
|
||||
address _parentRegistry
|
||||
)
|
||||
public
|
||||
UsernameRegistrar(
|
||||
_token,
|
||||
_ensRegistry,
|
||||
_resolver,
|
||||
_ensNode,
|
||||
_slashMechanism,
|
||||
_parentRegistry
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
30
contracts/mocks/UpdatedDummy2UsernameRegistrar.sol
Normal file
30
contracts/mocks/UpdatedDummy2UsernameRegistrar.sol
Normal file
@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "./Dummy2UsernameRegistrar.sol";
|
||||
|
||||
contract UpdatedDummy2UsernameRegistrar is Dummy2UsernameRegistrar {
|
||||
|
||||
constructor(
|
||||
ERC20Token _token,
|
||||
ENS _ensRegistry,
|
||||
PublicResolver _resolver,
|
||||
bytes32 _ensNode,
|
||||
address _slashMechanism,
|
||||
address _parentRegistry
|
||||
)
|
||||
public
|
||||
Dummy2UsernameRegistrar(
|
||||
_token,
|
||||
_ensRegistry,
|
||||
_resolver,
|
||||
_ensNode,
|
||||
_slashMechanism,
|
||||
_parentRegistry
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
30
contracts/mocks/UpdatedDummyUsernameRegistrar.sol
Normal file
30
contracts/mocks/UpdatedDummyUsernameRegistrar.sol
Normal file
@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "./DummyUsernameRegistrar.sol";
|
||||
|
||||
contract UpdatedDummyUsernameRegistrar is DummyUsernameRegistrar {
|
||||
|
||||
constructor(
|
||||
ERC20Token _token,
|
||||
ENS _ensRegistry,
|
||||
PublicResolver _resolver,
|
||||
bytes32 _ensNode,
|
||||
address _slashMechanism,
|
||||
address _parentRegistry
|
||||
)
|
||||
public
|
||||
DummyUsernameRegistrar(
|
||||
_token,
|
||||
_ensRegistry,
|
||||
_resolver,
|
||||
_ensNode,
|
||||
_slashMechanism,
|
||||
_parentRegistry
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
30
contracts/mocks/UpdatedUsernameRegistrar.sol
Normal file
30
contracts/mocks/UpdatedUsernameRegistrar.sol
Normal file
@ -0,0 +1,30 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "../registry/UsernameRegistrar.sol";
|
||||
|
||||
contract UpdatedUsernameRegistrar is UsernameRegistrar {
|
||||
|
||||
constructor(
|
||||
ERC20Token _token,
|
||||
ENS _ensRegistry,
|
||||
PublicResolver _resolver,
|
||||
bytes32 _ensNode,
|
||||
address _slashMechanism,
|
||||
address _parentRegistry
|
||||
)
|
||||
public
|
||||
UsernameRegistrar(
|
||||
_token,
|
||||
_ensRegistry,
|
||||
_resolver,
|
||||
_ensNode,
|
||||
_slashMechanism,
|
||||
_parentRegistry
|
||||
)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
141
contracts/registry/SlashMechanism.sol
Normal file
141
contracts/registry/SlashMechanism.sol
Normal file
@ -0,0 +1,141 @@
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "./UsernameRegistrar.sol";
|
||||
import "../common/MerkleProof.sol";
|
||||
|
||||
/**
|
||||
* @author Ricardo Guilherme Schmidt (Status Research & Development GmbH)
|
||||
* @notice Defines static rules for slashing usernames
|
||||
*/
|
||||
contract SlashMechanism {
|
||||
|
||||
struct SlashReserve {
|
||||
address reserver;
|
||||
uint256 blockNumber;
|
||||
UsernameRegistrar registrar;
|
||||
}
|
||||
|
||||
mapping (bytes32 => SlashReserve) public reservedSlashers;
|
||||
//Slashing conditions
|
||||
uint256 public usernameMinLength;
|
||||
bytes32 public reservedUsernamesMerkleRoot;
|
||||
|
||||
constructor(
|
||||
uint256 _usernameMinLength,
|
||||
bytes32 _reservedUsernamesMerkleRoot
|
||||
) public {
|
||||
usernameMinLength = _usernameMinLength;
|
||||
reservedUsernamesMerkleRoot = _reservedUsernamesMerkleRoot;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice secretly reserve the slashing reward to `msg.sender`
|
||||
* @param _registrar address of the registrar with the offending name
|
||||
* @param _secret keccak256(abi.encodePacked(label, reserveSecret)), label being the username label and reserveSecret a random number.
|
||||
*/
|
||||
function reserveSlash(UsernameRegistrar _registrar, bytes32 _secret) external {
|
||||
require(reservedSlashers[_secret].blockNumber == 0, "Already Reserved");
|
||||
reservedSlashers[_secret] = SlashReserve(msg.sender, block.number, _registrar);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Slash username smaller then `usernameMinLength`.
|
||||
* @param _username Raw value of offending username.
|
||||
* @param _reserveSecret number used in reserve secret generation.
|
||||
*/
|
||||
function slashSmallUsername(
|
||||
string calldata _username,
|
||||
uint256 _reserveSecret
|
||||
)
|
||||
external
|
||||
{
|
||||
bytes memory username = bytes(_username);
|
||||
require(username.length < usernameMinLength, "Not a small username.");
|
||||
slashUsername(_username, _reserveSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Slash username starting with "0x" and with length greater than 12.
|
||||
* @param _username Raw value of offending username.
|
||||
* @param _reserveSecret number used in reserve secret generation.
|
||||
*/
|
||||
function slashAddressLikeUsername(
|
||||
string calldata _username,
|
||||
uint256 _reserveSecret
|
||||
)
|
||||
external
|
||||
{
|
||||
bytes memory username = bytes(_username);
|
||||
require(username.length > 12, "Too small to look like an address.");
|
||||
require(username[0] == byte("0"), "First character need to be 0");
|
||||
require(username[1] == byte("x"), "Second character need to be x");
|
||||
for(uint i = 2; i < 7; i++){
|
||||
uint8 b = uint8(username[i]);
|
||||
require((b >= 48 && b <= 57) || (b >= 97 && b <= 102), "Does not look like an address");
|
||||
}
|
||||
slashUsername(_username, _reserveSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Slash username that is exactly a reserved name.
|
||||
* @param _username Raw value of offending username.
|
||||
* @param _proof Merkle proof that name is listed on merkle tree.
|
||||
* @param _reserveSecret number used in reserve secret generation.
|
||||
*/
|
||||
function slashReservedUsername(
|
||||
string calldata _username,
|
||||
bytes32[] calldata _proof,
|
||||
uint256 _reserveSecret
|
||||
)
|
||||
external
|
||||
{
|
||||
bytes memory username = bytes(_username);
|
||||
require(
|
||||
MerkleProof.verifyProof(
|
||||
_proof,
|
||||
reservedUsernamesMerkleRoot,
|
||||
keccak256(username)
|
||||
),
|
||||
"Invalid Proof."
|
||||
);
|
||||
slashUsername(_username, _reserveSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Slash username that contains a non alphanumeric character.
|
||||
* @param _username Raw value of offending username.
|
||||
* @param _offendingPos Position of non alphanumeric character.
|
||||
* @param _reserveSecret number used in reserve secret generation.
|
||||
*/
|
||||
function slashInvalidUsername(
|
||||
string calldata _username,
|
||||
uint256 _offendingPos,
|
||||
uint256 _reserveSecret
|
||||
)
|
||||
external
|
||||
{
|
||||
bytes memory username = bytes(_username);
|
||||
require(username.length > _offendingPos, "Invalid position.");
|
||||
uint8 b = uint8(username[_offendingPos]);
|
||||
|
||||
require(!((b >= 48 && b <= 57) || (b >= 97 && b <= 122)), "Not invalid character.");
|
||||
|
||||
slashUsername(_username, _reserveSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev Checks for reservation and requests username slashing in the selected registrar.
|
||||
* @param _username Raw value of offending username.
|
||||
* @param _reserveSecret number used in reserve secret generation.
|
||||
*/
|
||||
function slashUsername(string memory _username, uint256 _reserveSecret) internal{
|
||||
bytes32 secret = keccak256(abi.encodePacked(_username, _reserveSecret));
|
||||
SlashReserve memory reserve = reservedSlashers[secret];
|
||||
require(reserve.reserver != address(0), "Not reserved.");
|
||||
require(reserve.blockNumber < block.number, "Cannot reveal in same block");
|
||||
delete reservedSlashers[secret];
|
||||
reserve.registrar.slashUsername(_username, reserve.reserver);
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "../common/MerkleProof.sol";
|
||||
import "../common/Controlled.sol";
|
||||
import "../token/ERC20Token.sol";
|
||||
import "../token/ApproveAndCallFallBack.sol";
|
||||
@ -20,11 +21,9 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
|
||||
uint256 public constant releaseDelay = 365 days;
|
||||
mapping (bytes32 => Account) public accounts;
|
||||
mapping (bytes32 => SlashReserve) reservedSlashers;
|
||||
|
||||
//Slashing conditions
|
||||
uint256 public usernameMinLength;
|
||||
bytes32 public reservedUsernamesMerkleRoot;
|
||||
uint256 public lastUpdate;
|
||||
address public slashMechanism;
|
||||
|
||||
event RegistryState(RegistrarState state);
|
||||
event RegistryPrice(uint256 price);
|
||||
@ -43,10 +42,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
address owner;
|
||||
}
|
||||
|
||||
struct SlashReserve {
|
||||
address reserver;
|
||||
uint256 blockNumber;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @notice Callable only by `parentRegistry()` to continue migration of ENSSubdomainRegistry.
|
||||
@ -64,8 +60,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
* @param _ensRegistry Ethereum Name Service root contract address.
|
||||
* @param _resolver Public Resolver for resolving usernames.
|
||||
* @param _ensNode ENS node (domain) being used for usernames subnodes (subdomain)
|
||||
* @param _usernameMinLength Minimum length of usernames
|
||||
* @param _reservedUsernamesMerkleRoot Merkle root of reserved usernames
|
||||
* @param _slashMechanism Slashing mechanism address
|
||||
* @param _parentRegistry Address of old registry (if any) for optional account migration.
|
||||
*/
|
||||
constructor(
|
||||
@ -73,8 +68,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
ENS _ensRegistry,
|
||||
PublicResolver _resolver,
|
||||
bytes32 _ensNode,
|
||||
uint256 _usernameMinLength,
|
||||
bytes32 _reservedUsernamesMerkleRoot,
|
||||
address _slashMechanism,
|
||||
address _parentRegistry
|
||||
)
|
||||
public
|
||||
@ -87,8 +81,8 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
ensRegistry = _ensRegistry;
|
||||
resolver = _resolver;
|
||||
ensNode = _ensNode;
|
||||
usernameMinLength = _usernameMinLength;
|
||||
reservedUsernamesMerkleRoot = _reservedUsernamesMerkleRoot;
|
||||
slashMechanism = _slashMechanism;
|
||||
lastUpdate = block.timestamp;
|
||||
parentRegistry = _parentRegistry;
|
||||
setState(RegistrarState.Inactive);
|
||||
}
|
||||
@ -101,9 +95,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
* - User deposits are completely protected. The contract controller cannot access them.
|
||||
* - User's address(es) will be publicly associated with the ENS name.
|
||||
* - User must authorise the contract to transfer `price` `token.name()` on their behalf.
|
||||
* - Usernames registered with less then `usernameMinLength` characters can be slashed.
|
||||
* - Usernames contained in the merkle tree of root `reservedUsernamesMerkleRoot` can be slashed.
|
||||
* - Usernames starting with `0x` and bigger then 12 characters can be slashed.
|
||||
* - Usernames registered can be slashed if offending the `slashMechanism` contract rules.
|
||||
* - If terms of the contract change—e.g. Status makes contract upgrades—the user has the right to release the username and get their deposit back.
|
||||
* @param _label Choosen unowned username hash.
|
||||
* @param _account Optional address to set at public resolver.
|
||||
@ -138,7 +130,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
require(account.creationTime > 0, "Username not registered.");
|
||||
if (state == RegistrarState.Active) {
|
||||
require(msg.sender == ensRegistry.owner(namehash), "Not owner of ENS node.");
|
||||
require(block.timestamp > account.creationTime + releaseDelay, "Release period not reached.");
|
||||
require(block.timestamp > account.creationTime + releaseDelay || lastUpdate > account.creationTime, "Release period not reached.");
|
||||
} else {
|
||||
require(msg.sender == account.owner, "Not the former account owner.");
|
||||
}
|
||||
@ -154,10 +146,10 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
} else {
|
||||
address newOwner = ensRegistry.owner(ensNode);
|
||||
//Low level call, case dropUsername not implemented or failing, proceed release.
|
||||
//Invert (!) to supress warning, return of this call have no use.
|
||||
!newOwner.call.gas(80000)(
|
||||
abi.encodeWithSignature(
|
||||
"dropUsername(bytes32)",
|
||||
//Return of this call have no use.
|
||||
newOwner.call.gas(80000)(
|
||||
abi.encodeWithSelector(
|
||||
this.dropUsername.selector,
|
||||
_label
|
||||
)
|
||||
);
|
||||
@ -184,102 +176,13 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
emit UsernameOwner(namehash, msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice secretly reserve the slashing reward to `msg.sender`
|
||||
* @param _secret keccak256(abi.encodePacked(namehash, creationTime, reserveSecret))
|
||||
*/
|
||||
function reserveSlash(bytes32 _secret) external {
|
||||
require(reservedSlashers[_secret].blockNumber == 0, "Already Reserved");
|
||||
reservedSlashers[_secret] = SlashReserve(msg.sender, block.number);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Slash username smaller then `usernameMinLength`.
|
||||
* @param _username Raw value of offending username.
|
||||
*/
|
||||
function slashSmallUsername(
|
||||
string _username,
|
||||
uint256 _reserveSecret
|
||||
)
|
||||
external
|
||||
{
|
||||
bytes memory username = bytes(_username);
|
||||
require(username.length < usernameMinLength, "Not a small username.");
|
||||
slashUsername(username, _reserveSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Slash username starting with "0x" and with length greater than 12.
|
||||
* @param _username Raw value of offending username.
|
||||
*/
|
||||
function slashAddressLikeUsername(
|
||||
string _username,
|
||||
uint256 _reserveSecret
|
||||
)
|
||||
external
|
||||
{
|
||||
bytes memory username = bytes(_username);
|
||||
require(username.length > 12, "Too small to look like an address.");
|
||||
require(username[0] == byte("0"), "First character need to be 0");
|
||||
require(username[1] == byte("x"), "Second character need to be x");
|
||||
for(uint i = 2; i < 7; i++){
|
||||
byte b = username[i];
|
||||
require((b >= 48 && b <= 57) || (b >= 97 && b <= 102), "Does not look like an address");
|
||||
}
|
||||
slashUsername(username, _reserveSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Slash username that is exactly a reserved name.
|
||||
* @param _username Raw value of offending username.
|
||||
* @param _proof Merkle proof that name is listed on merkle tree.
|
||||
*/
|
||||
function slashReservedUsername(
|
||||
string _username,
|
||||
bytes32[] _proof,
|
||||
uint256 _reserveSecret
|
||||
)
|
||||
external
|
||||
{
|
||||
bytes memory username = bytes(_username);
|
||||
require(
|
||||
MerkleProof.verifyProof(
|
||||
_proof,
|
||||
reservedUsernamesMerkleRoot,
|
||||
keccak256(username)
|
||||
),
|
||||
"Invalid Proof."
|
||||
);
|
||||
slashUsername(username, _reserveSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Slash username that contains a non alphanumeric character.
|
||||
* @param _username Raw value of offending username.
|
||||
* @param _offendingPos Position of non alphanumeric character.
|
||||
*/
|
||||
function slashInvalidUsername(
|
||||
string _username,
|
||||
uint256 _offendingPos,
|
||||
uint256 _reserveSecret
|
||||
)
|
||||
external
|
||||
{
|
||||
bytes memory username = bytes(_username);
|
||||
require(username.length > _offendingPos, "Invalid position.");
|
||||
byte b = username[_offendingPos];
|
||||
|
||||
require(!((b >= 48 && b <= 57) || (b >= 97 && b <= 122)), "Not invalid character.");
|
||||
|
||||
slashUsername(username, _reserveSecret);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Clear resolver and ownership of unowned subdomians.
|
||||
* @param _labels Sequence to erase.
|
||||
*/
|
||||
function eraseNode(
|
||||
bytes32[] _labels
|
||||
bytes32[] calldata _labels
|
||||
)
|
||||
external
|
||||
{
|
||||
@ -292,8 +195,8 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
if(len > 1) {
|
||||
eraseNodeHierarchy(len - 2, _labels, subnode);
|
||||
}
|
||||
ensRegistry.setResolver(subnode, 0);
|
||||
ensRegistry.setOwner(subnode, 0);
|
||||
ensRegistry.setResolver(subnode, address(0));
|
||||
ensRegistry.setOwner(subnode, address(0));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -312,7 +215,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
Account memory account = accounts[_label];
|
||||
delete accounts[_label];
|
||||
|
||||
token.approve(_newRegistry, account.balance);
|
||||
token.approve(address(_newRegistry), account.balance);
|
||||
_newRegistry.migrateUsername(
|
||||
_label,
|
||||
account.balance,
|
||||
@ -351,6 +254,21 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
resolver = PublicResolver(_resolver);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Updates slash mechanism.
|
||||
* @param _slashMechanism New Slash Mechanism
|
||||
*/
|
||||
function setSlashMechanism(
|
||||
address _slashMechanism
|
||||
)
|
||||
external
|
||||
onlyController
|
||||
{
|
||||
lastUpdate = block.timestamp;
|
||||
require(_slashMechanism != address(0), "Zero address for _slashMechanism");
|
||||
slashMechanism = _slashMechanism;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice Updates registration price.
|
||||
* @param _price New registration price.
|
||||
@ -403,7 +321,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
**/
|
||||
function withdrawExcessBalance(
|
||||
address _token,
|
||||
address _beneficiary
|
||||
address payable _beneficiary
|
||||
)
|
||||
external
|
||||
onlyController
|
||||
@ -444,7 +362,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
|
||||
/**
|
||||
* @notice Gets registration price.
|
||||
* @return Registration price.
|
||||
* @return registryPrice Registration price.
|
||||
**/
|
||||
function getPrice()
|
||||
external
|
||||
@ -457,7 +375,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
/**
|
||||
* @notice reads amount tokens locked in username
|
||||
* @param _label Username hash.
|
||||
* @return Locked username balance.
|
||||
* @return accountBalance Locked username balance.
|
||||
**/
|
||||
function getAccountBalance(bytes32 _label)
|
||||
external
|
||||
@ -471,7 +389,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
* @notice reads username account owner at this contract,
|
||||
* which can release or migrate in case of upgrade.
|
||||
* @param _label Username hash.
|
||||
* @return Username account owner.
|
||||
* @return owner Username account owner.
|
||||
**/
|
||||
function getAccountOwner(bytes32 _label)
|
||||
external
|
||||
@ -484,7 +402,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
/**
|
||||
* @notice reads when the account was registered
|
||||
* @param _label Username hash.
|
||||
* @return Registration time.
|
||||
* @return creationTime Registration time.
|
||||
**/
|
||||
function getCreationTime(bytes32 _label)
|
||||
external
|
||||
@ -497,7 +415,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
/**
|
||||
* @notice calculate time where username can be released
|
||||
* @param _label Username hash.
|
||||
* @return Exact time when username can be released.
|
||||
* @return releaseTime Exact time when username can be released.
|
||||
**/
|
||||
function getExpirationTime(bytes32 _label)
|
||||
external
|
||||
@ -513,7 +431,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
/**
|
||||
* @notice calculate reward part an account could payout on slash
|
||||
* @param _label Username hash.
|
||||
* @return Part of reward
|
||||
* @return partReward Part of reward
|
||||
**/
|
||||
function getSlashRewardPart(bytes32 _label)
|
||||
external
|
||||
@ -537,7 +455,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
address _from,
|
||||
uint256 _amount,
|
||||
address _token,
|
||||
bytes _data
|
||||
bytes memory _data
|
||||
)
|
||||
public
|
||||
{
|
||||
@ -552,7 +470,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
bytes32 pubkeyB;
|
||||
(sig, label, account, pubkeyA, pubkeyB) = abiDecodeRegister(_data);
|
||||
require(
|
||||
sig == bytes4(0xb82fedbb), //bytes4(keccak256("register(bytes32,address,bytes32,bytes32)"))
|
||||
sig == this.register.selector,
|
||||
"Wrong method selector"
|
||||
);
|
||||
registerUser(_from, label, account, pubkeyA, pubkeyB);
|
||||
@ -647,7 +565,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
if (resolvePubkey || resolveAccount) {
|
||||
//set to self the ownership to setup initial resolver
|
||||
ensRegistry.setSubnodeOwner(ensNode, _label, address(this));
|
||||
ensRegistry.setResolver(namehash, resolver); //default resolver
|
||||
ensRegistry.setResolver(namehash, address(resolver)); //default resolver
|
||||
if (resolveAccount) {
|
||||
resolver.setAddr(namehash, _account);
|
||||
}
|
||||
@ -667,16 +585,18 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
* @param _username Username being slashed.
|
||||
*/
|
||||
function slashUsername(
|
||||
bytes _username,
|
||||
uint256 _reserveSecret
|
||||
string calldata _username,
|
||||
address _reserver
|
||||
)
|
||||
internal
|
||||
external
|
||||
{
|
||||
bytes32 label = keccak256(_username);
|
||||
require(msg.sender == slashMechanism, "Unauthorized");
|
||||
bytes32 label = keccak256(bytes(_username));
|
||||
bytes32 namehash = keccak256(abi.encodePacked(ensNode, label));
|
||||
uint256 amountToTransfer = 0;
|
||||
uint256 creationTime = accounts[label].creationTime;
|
||||
address owner = ensRegistry.owner(namehash);
|
||||
address beneficiary = _reserver;
|
||||
if(creationTime == 0) {
|
||||
require(
|
||||
owner != address(0) ||
|
||||
@ -686,6 +606,9 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
} else {
|
||||
assert(creationTime != block.timestamp);
|
||||
amountToTransfer = accounts[label].balance;
|
||||
if(lastUpdate > creationTime) {
|
||||
beneficiary = accounts[label].owner;
|
||||
}
|
||||
delete accounts[label];
|
||||
}
|
||||
|
||||
@ -695,15 +618,10 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
|
||||
if (amountToTransfer > 0) {
|
||||
reserveAmount -= amountToTransfer;
|
||||
uint256 partialDeposit = amountToTransfer / 3;
|
||||
amountToTransfer = partialDeposit * 2; // reserve 1/3 to network (controller)
|
||||
bytes32 secret = keccak256(abi.encodePacked(namehash, creationTime, _reserveSecret));
|
||||
SlashReserve memory reserve = reservedSlashers[secret];
|
||||
require(reserve.reserver != address(0), "Not reserved.");
|
||||
require(reserve.blockNumber < block.number, "Cannot reveal in same block");
|
||||
delete reservedSlashers[secret];
|
||||
|
||||
require(token.transfer(reserve.reserver, amountToTransfer), "Error in transfer.");
|
||||
if(lastUpdate < creationTime) {
|
||||
amountToTransfer = (amountToTransfer * 2) / 3; // reserve 1/3 to network (controller)
|
||||
}
|
||||
require(token.transfer(beneficiary, amountToTransfer), "Error in transfer.");
|
||||
}
|
||||
emit UsernameOwner(namehash, address(0));
|
||||
}
|
||||
@ -721,7 +639,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
*/
|
||||
function eraseNodeHierarchy(
|
||||
uint _idx,
|
||||
bytes32[] _labels,
|
||||
bytes32[] memory _labels,
|
||||
bytes32 _subnode
|
||||
)
|
||||
private
|
||||
@ -736,8 +654,8 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
}
|
||||
|
||||
// Erase the resolver and owner records
|
||||
ensRegistry.setResolver(subnode, 0);
|
||||
ensRegistry.setOwner(subnode, 0);
|
||||
ensRegistry.setResolver(subnode, address(0));
|
||||
ensRegistry.setOwner(subnode, address(0));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -746,7 +664,7 @@ contract UsernameRegistrar is Controlled, ApproveAndCallFallBack {
|
||||
* @return Decoded registry call.
|
||||
*/
|
||||
function abiDecodeRegister(
|
||||
bytes _data
|
||||
bytes memory _data
|
||||
)
|
||||
private
|
||||
pure
|
||||
|
@ -1,12 +1,14 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import { MerkleProof } from "../common/MerkleProof.sol";
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "../common/MerkleProof.sol";
|
||||
|
||||
|
||||
contract MerkleProofWrapper {
|
||||
|
||||
function verifyProof(
|
||||
bytes32[] _proof,
|
||||
bytes32[] memory _proof,
|
||||
bytes32 _root,
|
||||
bytes32 _leaf
|
||||
)
|
||||
|
@ -1,5 +1,7 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
contract ApproveAndCallFallBack {
|
||||
function receiveApproval(address from, uint256 _amount, address _token, bytes _data) public;
|
||||
function receiveApproval(address from, uint256 _amount, address _token, bytes memory _data) public;
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "./ERC20Token.sol";
|
||||
|
||||
@ -43,7 +45,7 @@ contract ERC20Receiver {
|
||||
)
|
||||
external
|
||||
{
|
||||
require(_token.allowance(msg.sender, address(this)) >= _amount);
|
||||
require(_token.allowance(msg.sender, address(this)) >= _amount, "Bad argument");
|
||||
_depositToken(msg.sender, _token, _amount);
|
||||
}
|
||||
|
||||
@ -65,7 +67,7 @@ contract ERC20Receiver {
|
||||
)
|
||||
private
|
||||
{
|
||||
require(_amount > 0);
|
||||
require(_amount > 0, "Bad argument");
|
||||
if (_token.transferFrom(_from, address(this), _amount)) {
|
||||
tokenBalances[address(_token)][_from] += _amount;
|
||||
emit TokenDeposited(address(_token), _from, _amount);
|
||||
@ -79,10 +81,10 @@ contract ERC20Receiver {
|
||||
)
|
||||
private
|
||||
{
|
||||
require(_amount > 0);
|
||||
require(tokenBalances[address(_token)][_from] >= _amount);
|
||||
require(_amount > 0, "Bad argument");
|
||||
require(tokenBalances[address(_token)][_from] >= _amount, "Insufficient funds");
|
||||
tokenBalances[address(_token)][_from] -= _amount;
|
||||
require(_token.transfer(_from, _amount));
|
||||
require(_token.transfer(_from, _amount), "Transfer fail");
|
||||
emit TokenWithdrawn(address(_token), _from, _amount);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
// Abstract contract for the full ERC 20 Token standard
|
||||
// https://github.com/ethereum/EIPs/issues/20
|
||||
@ -9,7 +11,7 @@ interface ERC20Token {
|
||||
* @notice send `_value` token to `_to` from `msg.sender`
|
||||
* @param _to The address of the recipient
|
||||
* @param _value The amount of token to be transferred
|
||||
* @return Whether the transfer was successful or not
|
||||
* @return success Whether the transfer was successful or not
|
||||
*/
|
||||
function transfer(address _to, uint256 _value) external returns (bool success);
|
||||
|
||||
@ -17,7 +19,7 @@ interface ERC20Token {
|
||||
* @notice `msg.sender` approves `_spender` to spend `_value` tokens
|
||||
* @param _spender The address of the account able to transfer the tokens
|
||||
* @param _value The amount of tokens to be approved for transfer
|
||||
* @return Whether the approval was successful or not
|
||||
* @return success Whether the approval was successful or not
|
||||
*/
|
||||
function approve(address _spender, uint256 _value) external returns (bool success);
|
||||
|
||||
@ -26,25 +28,26 @@ interface ERC20Token {
|
||||
* @param _from The address of the sender
|
||||
* @param _to The address of the recipient
|
||||
* @param _value The amount of token to be transferred
|
||||
* @return Whether the transfer was successful or not
|
||||
* @return success Whether the transfer was successful or not
|
||||
*/
|
||||
function transferFrom(address _from, address _to, uint256 _value) external returns (bool success);
|
||||
|
||||
/**
|
||||
* @param _owner The address from which the balance will be retrieved
|
||||
* @return The balance
|
||||
* @return balance The balance
|
||||
*/
|
||||
function balanceOf(address _owner) external view returns (uint256 balance);
|
||||
|
||||
/**
|
||||
* @param _owner The address of the account owning tokens
|
||||
* @param _spender The address of the account able to transfer the tokens
|
||||
* @return Amount of remaining tokens allowed to spent
|
||||
* @return remaining Amount of remaining tokens allowed to spent
|
||||
*/
|
||||
function allowance(address _owner, address _spender) external view returns (uint256 remaining);
|
||||
|
||||
/**
|
||||
* @notice return total supply of tokens
|
||||
* @return supply Total supply of the token.
|
||||
*/
|
||||
function totalSupply() external view returns (uint256 supply);
|
||||
|
||||
|
@ -1,10 +1,12 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "./ERC20Token.sol";
|
||||
|
||||
contract StandardToken is ERC20Token {
|
||||
|
||||
uint256 private supply;
|
||||
uint256 private totalTokens;
|
||||
mapping (address => uint256) balances;
|
||||
mapping (address => mapping (address => uint256)) allowed;
|
||||
|
||||
@ -67,9 +69,9 @@ contract StandardToken is ERC20Token {
|
||||
function totalSupply()
|
||||
external
|
||||
view
|
||||
returns(uint256 currentTotalSupply)
|
||||
returns(uint256 supply)
|
||||
{
|
||||
return supply;
|
||||
return totalTokens;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,8 +100,8 @@ contract StandardToken is ERC20Token {
|
||||
internal
|
||||
{
|
||||
balances[_to] += _amount;
|
||||
supply += _amount;
|
||||
emit Transfer(0x0, _to, _amount);
|
||||
totalTokens += _amount;
|
||||
emit Transfer(address(0x0), _to, _amount);
|
||||
}
|
||||
|
||||
function transfer(
|
||||
@ -113,7 +115,7 @@ contract StandardToken is ERC20Token {
|
||||
if (balances[_from] >= _value && _value > 0) {
|
||||
balances[_from] -= _value;
|
||||
if(_to == address(0)) {
|
||||
supply -= _value;
|
||||
totalTokens -= _value;
|
||||
} else {
|
||||
balances[_to] += _value;
|
||||
}
|
||||
|
@ -1,4 +1,6 @@
|
||||
pragma solidity ^0.4.24;
|
||||
// SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
pragma solidity 0.5.11;
|
||||
|
||||
import "./StandardToken.sol";
|
||||
import "./ApproveAndCallFallBack.sol";
|
||||
@ -18,12 +20,13 @@ contract TestToken is StandardToken {
|
||||
mint(msg.sender, _amount);
|
||||
}
|
||||
|
||||
function approveAndCall(address _spender, uint256 _value, bytes _extraData)
|
||||
|
||||
function approveAndCall(address _spender, uint256 _value, bytes calldata _extraData)
|
||||
external
|
||||
returns (bool success)
|
||||
{
|
||||
approve(msg.sender, _spender, _value);
|
||||
ApproveAndCallFallBack(_spender).receiveApproval(msg.sender, _value, this, _extraData);
|
||||
ApproveAndCallFallBack(_spender).receiveApproval(msg.sender, _value, address(this), _extraData);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
22
embark.json
22
embark.json
@ -9,9 +9,23 @@
|
||||
"buildDir": "dist/",
|
||||
"config": "config/",
|
||||
"versions": {
|
||||
"web3": "1.0.0-beta.34",
|
||||
"solc": "0.4.24",
|
||||
"ipfs-api": "17.2.4"
|
||||
"solc": "0.5.11"
|
||||
},
|
||||
"plugins": {}
|
||||
"plugins": {
|
||||
"embark-ipfs": {},
|
||||
"embark-swarm": {},
|
||||
"embark-whisper-geth": {},
|
||||
"embark-geth": {},
|
||||
"embark-parity": {},
|
||||
"embark-profiler": {},
|
||||
"embark-graph": {},
|
||||
"embark-basic-pipeline": {}
|
||||
},
|
||||
"options": {
|
||||
"solc": {
|
||||
"optimize": true,
|
||||
"optimize-runs": 200
|
||||
}
|
||||
},
|
||||
"generationDir": "embarkArtifacts"
|
||||
}
|
26191
package-lock.json
generated
Normal file
26191
package-lock.json
generated
Normal file
File diff suppressed because it is too large
Load Diff
16
package.json
16
package.json
@ -48,6 +48,21 @@
|
||||
"web3-utils": "^1.0.0-beta.34"
|
||||
},
|
||||
"devDependencies": {
|
||||
"embark": "^6.0.0",
|
||||
"embark-basic-pipeline": "^6.0.0",
|
||||
"embark-geth": "^6.0.0",
|
||||
"embark-graph": "^6.0.0",
|
||||
"embark-ipfs": "^6.0.0",
|
||||
"embark-parity": "^6.0.0",
|
||||
"embark-profiler": "^6.0.0",
|
||||
"embark-swarm": "^6.0.0",
|
||||
"embark-whisper-geth": "^6.0.0",
|
||||
"embarkjs": "^6.0.0",
|
||||
"embarkjs-ens": "^6.0.0",
|
||||
"embarkjs-ipfs": "^6.0.0",
|
||||
"embarkjs-swarm": "^6.0.0",
|
||||
"embarkjs-web3": "^6.0.0",
|
||||
"embarkjs-whisper": "^6.0.0",
|
||||
"@babel/plugin-proposal-class-properties": "^7.0.0",
|
||||
"@babel/plugin-proposal-decorators": "^7.0.0",
|
||||
"@babel/plugin-proposal-export-namespace-from": "^7.0.0",
|
||||
@ -58,6 +73,7 @@
|
||||
"@babel/plugin-proposal-throw-expressions": "^7.0.0",
|
||||
"@babel/plugin-syntax-dynamic-import": "^7.0.0",
|
||||
"@babel/plugin-syntax-import-meta": "^7.0.0",
|
||||
|
||||
"eslint": "^4.19.1",
|
||||
"eslint-config-airbnb": "^16.1.0",
|
||||
"eslint-plugin-import": "^2.12.0",
|
||||
|
@ -1,11 +1,8 @@
|
||||
|
||||
const ERC20Receiver = require('Embark/contracts/ERC20Receiver');
|
||||
const ERC20Receiver = artifacts.require('ERC20Receiver');
|
||||
|
||||
exports.config = {
|
||||
contracts : {
|
||||
"ERC20Receiver": {
|
||||
}
|
||||
}
|
||||
exports.contracts = {
|
||||
"ERC20Receiver": {}
|
||||
}
|
||||
|
||||
exports.Test = (ERC20Token) => {
|
||||
@ -26,14 +23,14 @@ exports.Test = (ERC20Token) => {
|
||||
let result0 = await ERC20Token.methods.balanceOf(accounts[0]).call();
|
||||
let result1 = await ERC20Token.methods.balanceOf(accounts[1]).call();
|
||||
|
||||
assert.equal(result0, +initialBalance0-1, "account 0 balance unexpected");
|
||||
assert.equal(result1, +initialBalance1+1, "account 1 balance unexpected");
|
||||
assert.equal(+result0, +initialBalance0-1, "account 0 balance unexpected");
|
||||
assert.equal(+result1, +initialBalance1+1, "account 1 balance unexpected");
|
||||
});
|
||||
|
||||
it("should set approved amount", async function() {
|
||||
await ERC20Token.methods.approve(accounts[2],10000000).send({from: accounts[0]});
|
||||
let result = await ERC20Token.methods.allowance(accounts[0], accounts[2]).call();
|
||||
assert.equal(result, 10000000);
|
||||
assert.equal(+result, 10000000);
|
||||
});
|
||||
|
||||
it("should consume allowance amount", async function() {
|
||||
@ -41,7 +38,7 @@ exports.Test = (ERC20Token) => {
|
||||
await ERC20Token.methods.transferFrom(accounts[0], accounts[0],1).send({from: accounts[2]});
|
||||
let result = await ERC20Token.methods.allowance(accounts[0], accounts[2]).call();
|
||||
|
||||
assert.equal(result, +initialAllowance-1);
|
||||
assert.equal(+result, +initialAllowance-1);
|
||||
});
|
||||
|
||||
it("should transfer approved amount", async function() {
|
||||
@ -51,15 +48,15 @@ exports.Test = (ERC20Token) => {
|
||||
let result0 = await ERC20Token.methods.balanceOf(accounts[0]).call();
|
||||
let result1 = await ERC20Token.methods.balanceOf(accounts[1]).call();
|
||||
|
||||
assert.equal(result0, +initialBalance0-1);
|
||||
assert.equal(result1, +initialBalance1+1);
|
||||
assert.equal(+result0, +initialBalance0-1);
|
||||
assert.equal(+result1, +initialBalance1+1);
|
||||
});
|
||||
|
||||
|
||||
it("should unset approved amount", async function() {
|
||||
await ERC20Token.methods.approve(accounts[2],0).send({from: accounts[0]});
|
||||
let result = await ERC20Token.methods.allowance(accounts[0], accounts[2]).call();
|
||||
assert.equal(result, 0);
|
||||
assert.equal(+result, 0);
|
||||
});
|
||||
|
||||
it("should deposit approved amount to contract ERC20Receiver", async function() {
|
||||
@ -68,14 +65,14 @@ exports.Test = (ERC20Token) => {
|
||||
await ERC20Token.methods.approve(ERC20Receiver.address, 10).send({from: accounts[0]});
|
||||
await ERC20Receiver.methods.depositToken(ERC20Token.address, 10).send({from: accounts[0]});
|
||||
let result = await ERC20Receiver.methods.tokenBalanceOf(ERC20Token.address, accounts[0]).call();
|
||||
assert.equal(result, 10, "ERC20Receiver.tokenBalanceOf("+ERC20Token.address+","+accounts[0]+") wrong");
|
||||
assert.equal(+result, 10, "ERC20Receiver.tokenBalanceOf("+ERC20Token.address+","+accounts[0]+") wrong");
|
||||
});
|
||||
|
||||
it("should witdraw approved amount from contract ERC20Receiver", async function() {
|
||||
let tokenBalance = await ERC20Receiver.methods.tokenBalanceOf(ERC20Token.address, accounts[0]).call();
|
||||
await ERC20Receiver.methods.withdrawToken(ERC20Token.address, tokenBalance).send({from: accounts[0]});
|
||||
tokenBalance = await ERC20Receiver.methods.tokenBalanceOf(ERC20Token.address, accounts[0]).call();
|
||||
assert.equal(tokenBalance, 0, "ERC20Receiver.tokenBalanceOf("+ERC20Token.address+","+accounts[0]+") wrong");
|
||||
assert.equal(+tokenBalance, 0, "ERC20Receiver.tokenBalanceOf("+ERC20Token.address+","+accounts[0]+") wrong");
|
||||
});
|
||||
|
||||
//TODO: include checks for expected events fired
|
||||
|
@ -1,11 +1,11 @@
|
||||
const utils = require('../utils/testUtils.js');
|
||||
const ENSRegistry = require('Embark/contracts/ENSRegistry');
|
||||
const ENSRegistry = artifacts.require('ENSRegistry');
|
||||
const web3Utils = require('web3-utils');
|
||||
const namehash = require('eth-ens-namehash');
|
||||
|
||||
config({
|
||||
contracts: {
|
||||
"ENSRegistry": { },
|
||||
deploy: {"ENSRegistry": { }}
|
||||
}
|
||||
});
|
||||
|
||||
@ -57,10 +57,10 @@ contract('ENS', function () {
|
||||
|
||||
it('should allow setting the TTL', async () => {
|
||||
let result = await ENSRegistry.methods.setTTL(utils.zeroBytes32, 3600).send({from: accountsArr[1]});
|
||||
assert.equal(await ENSRegistry.methods.ttl(utils.zeroBytes32).call(), 3600);
|
||||
assert.equal(+await ENSRegistry.methods.ttl(utils.zeroBytes32).call(), 3600);
|
||||
let args = result.events.NewTTL.returnValues;
|
||||
assert.equal(args.node, utils.zeroBytes32);
|
||||
assert.equal(args.ttl, 3600);
|
||||
assert.equal(+args.ttl, 3600);
|
||||
});
|
||||
|
||||
it('should prevent setting the TTL by non-owners', async () => {
|
||||
|
@ -1,7 +1,7 @@
|
||||
const { MerkleTree } = require('../utils/merkleTree.js');
|
||||
const { sha3, bufferToHex } = require('ethereumjs-util');
|
||||
|
||||
const MerkleProofWrapper = require('Embark/contracts/MerkleProofWrapper');
|
||||
const MerkleProofWrapper = artifacts.require('MerkleProofWrapper');
|
||||
|
||||
var contractsConfig = {
|
||||
"MerkleProofWrapper": {
|
||||
@ -9,7 +9,7 @@ var contractsConfig = {
|
||||
}
|
||||
};
|
||||
|
||||
config({ contracts: contractsConfig });
|
||||
config({ contracts: { deploy: contractsConfig }});
|
||||
|
||||
contract('MerkleProof', function () {
|
||||
|
||||
|
@ -1,12 +1,14 @@
|
||||
const Utils = require('../utils/testUtils');
|
||||
const TestToken = require('Embark/contracts/TestToken');
|
||||
const TestToken = artifacts.require('TestToken');
|
||||
const ERC20TokenSpec = require('./abstract/erc20tokenspec');
|
||||
|
||||
config({
|
||||
contracts: {
|
||||
deploy: {
|
||||
"TestToken": {
|
||||
},
|
||||
...ERC20TokenSpec.config.contracts
|
||||
...ERC20TokenSpec.contracts
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@ -24,28 +26,28 @@ contract("TestToken", function() {
|
||||
let initialSupply = await TestToken.methods.totalSupply().call();
|
||||
await TestToken.methods.mint(100).send();
|
||||
let result = await TestToken.methods.totalSupply().call();
|
||||
assert.equal(result, +initialSupply+100);
|
||||
assert.equal(+result, +initialSupply+100);
|
||||
});
|
||||
|
||||
it("should increase accountBalance in mint", async function() {
|
||||
let initialBalance = await TestToken.methods.balanceOf(accounts[0]).call();
|
||||
await TestToken.methods.mint(100).send({from: accounts[0]});
|
||||
let result = await TestToken.methods.balanceOf(accounts[0]).call();
|
||||
assert.equal(result, +initialBalance+100);
|
||||
assert.equal(+result, +initialBalance+100);
|
||||
});
|
||||
|
||||
it("should burn account supply", async function() {
|
||||
let initialBalance = await TestToken.methods.balanceOf(accounts[0]).call();
|
||||
await TestToken.methods.transfer(Utils.zeroAddress, initialBalance).send({from: accounts[0]});
|
||||
assert.equal(await TestToken.methods.totalSupply().call(), 0);
|
||||
assert.equal(await TestToken.methods.balanceOf(accounts[0]).call(), 0);
|
||||
assert.equal(+await TestToken.methods.totalSupply().call(), 0);
|
||||
assert.equal(+await TestToken.methods.balanceOf(accounts[0]).call(), 0);
|
||||
})
|
||||
|
||||
it("should mint balances for ERC20TokenSpec", async function() {
|
||||
let initialBalance = 7 * 10 ^ 18;
|
||||
for(i=0;i<accounts.length;i++){
|
||||
await TestToken.methods.mint(initialBalance).send({from: accounts[i]})
|
||||
assert.equal(await TestToken.methods.balanceOf(accounts[i]).call(), initialBalance);
|
||||
assert.equal(+await TestToken.methods.balanceOf(accounts[i]).call(), initialBalance);
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -11,7 +11,7 @@ const registry = {
|
||||
registry: 'stateofus.eth',
|
||||
label: web3Utils.sha3('stateofus'),
|
||||
namehash: namehash.hash('stateofus.eth'),
|
||||
price: 100000000
|
||||
price: 1000
|
||||
}
|
||||
|
||||
const dummyRegistry = {
|
||||
@ -19,7 +19,7 @@ const dummyRegistry = {
|
||||
registry: 'dummyreg.eth',
|
||||
label: web3Utils.sha3('dummyreg'),
|
||||
namehash: namehash.hash('dummyreg.eth'),
|
||||
price: 100000000
|
||||
price: 1000
|
||||
}
|
||||
|
||||
|
||||
@ -28,7 +28,7 @@ const dummy2Registry = {
|
||||
registry: 'dummy2reg.eth',
|
||||
label: web3Utils.sha3('dummy2reg'),
|
||||
namehash: namehash.hash('dummy2reg.eth'),
|
||||
price: 100000000
|
||||
price: 1000
|
||||
}
|
||||
|
||||
// TODO: load file of reserved names and balance array lenght to be even
|
||||
@ -39,6 +39,7 @@ let accountsArr;
|
||||
config(
|
||||
{
|
||||
contracts: {
|
||||
deploy: {
|
||||
"TestToken": { },
|
||||
"ENSRegistry": {
|
||||
"onDeploy": [
|
||||
@ -50,69 +51,72 @@ config(
|
||||
"$ENSRegistry"
|
||||
]
|
||||
},
|
||||
"UsernameRegistrar": {
|
||||
"SlashMechanism": {
|
||||
"args": [
|
||||
"3",
|
||||
merkleRoot
|
||||
],
|
||||
}
|
||||
,"UsernameRegistrar": {
|
||||
"args": [
|
||||
"$TestToken",
|
||||
"$ENSRegistry",
|
||||
"$PublicResolver",
|
||||
registry.namehash,
|
||||
"3",
|
||||
merkleRoot,
|
||||
"0x0"
|
||||
"$SlashMechanism",
|
||||
"0x0000000000000000000000000000000000000000"
|
||||
],
|
||||
"onDeploy": [
|
||||
"await ENSRegistry.methods.setSubnodeOwner('0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae', '"+registry.label+"', UsernameRegistrar.address).send()",
|
||||
]
|
||||
},
|
||||
"UpdatedUsernameRegistrar": {
|
||||
"instanceOf" : "UsernameRegistrar",
|
||||
"args": [
|
||||
"$TestToken",
|
||||
"$ENSRegistry",
|
||||
"$PublicResolver",
|
||||
registry.namehash,
|
||||
"3",
|
||||
merkleRoot,
|
||||
"$SlashMechanism",
|
||||
"$UsernameRegistrar"
|
||||
]
|
||||
},
|
||||
"DummyUsernameRegistrar": {
|
||||
"instanceOf" : "UsernameRegistrar",
|
||||
"args": [
|
||||
"$TestToken",
|
||||
"$ENSRegistry",
|
||||
"$PublicResolver",
|
||||
dummyRegistry.namehash,
|
||||
"3",
|
||||
merkleRoot,
|
||||
"0x0"
|
||||
"$SlashMechanism",
|
||||
"0x0000000000000000000000000000000000000000"
|
||||
],
|
||||
"onDeploy": [
|
||||
"await ENSRegistry.methods.setSubnodeOwner('0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae', '"+dummyRegistry.label+"', DummyUsernameRegistrar.address).send()",
|
||||
]
|
||||
},
|
||||
"UpdatedDummyUsernameRegistrar": {
|
||||
"instanceOf" : "UsernameRegistrar",
|
||||
"args": [
|
||||
"$TestToken",
|
||||
"$ENSRegistry",
|
||||
"$PublicResolver",
|
||||
dummyRegistry.namehash,
|
||||
"3",
|
||||
merkleRoot,
|
||||
"$SlashMechanism",
|
||||
"$DummyUsernameRegistrar"
|
||||
]
|
||||
},
|
||||
"Dummy2SlashMechanism": {
|
||||
"args": [
|
||||
"3",
|
||||
utils.zeroBytes32
|
||||
],
|
||||
},
|
||||
"Dummy2UsernameRegistrar": {
|
||||
"instanceOf" : "UsernameRegistrar",
|
||||
"args": [
|
||||
"$TestToken",
|
||||
"$ENSRegistry",
|
||||
"$PublicResolver",
|
||||
dummy2Registry.namehash,
|
||||
"3",
|
||||
utils.zeroBytes32,
|
||||
"0x0"
|
||||
"$Dummy2SlashMechanism",
|
||||
"0x0000000000000000000000000000000000000000"
|
||||
],
|
||||
"onDeploy": [
|
||||
"await ENSRegistry.methods.setSubnodeOwner('0x93cdeb708b7545dc668eb9280176169d1c33cfd8ed6f04690a0bcc88a93fc4ae', '"+dummy2Registry.label+"', Dummy2UsernameRegistrar.address).send()",
|
||||
@ -120,32 +124,33 @@ config(
|
||||
]
|
||||
},
|
||||
"UpdatedDummy2UsernameRegistrar": {
|
||||
"instanceOf" : "UsernameRegistrar",
|
||||
"args": [
|
||||
"$TestToken",
|
||||
"$ENSRegistry",
|
||||
"$PublicResolver",
|
||||
dummy2Registry.namehash,
|
||||
"3",
|
||||
merkleRoot,
|
||||
"$SlashMechanism",
|
||||
"$Dummy2UsernameRegistrar"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
}, (_err, web3_accounts) => {
|
||||
accountsArr = web3_accounts
|
||||
}
|
||||
);
|
||||
|
||||
const TestToken = require('Embark/contracts/TestToken');
|
||||
const ENSRegistry = require('Embark/contracts/ENSRegistry');
|
||||
const PublicResolver = require('Embark/contracts/PublicResolver');
|
||||
const UsernameRegistrar = require('Embark/contracts/UsernameRegistrar');
|
||||
const UpdatedUsernameRegistrar = require('Embark/contracts/UpdatedUsernameRegistrar');
|
||||
const DummyUsernameRegistrar = require('Embark/contracts/DummyUsernameRegistrar');
|
||||
const UpdatedDummyUsernameRegistrar = require('Embark/contracts/UpdatedDummyUsernameRegistrar');
|
||||
const Dummy2UsernameRegistrar = require('Embark/contracts/Dummy2UsernameRegistrar');
|
||||
const UpdatedDummy2UsernameRegistrar = require('Embark/contracts/UpdatedDummy2UsernameRegistrar');
|
||||
const TestToken = artifacts.require('TestToken');
|
||||
const ENSRegistry = artifacts.require('ENSRegistry');
|
||||
const PublicResolver = artifacts.require('PublicResolver');
|
||||
const UsernameRegistrar = artifacts.require('UsernameRegistrar');
|
||||
const UpdatedUsernameRegistrar = artifacts.require('UpdatedUsernameRegistrar');
|
||||
const DummyUsernameRegistrar = artifacts.require('DummyUsernameRegistrar');
|
||||
const UpdatedDummyUsernameRegistrar = artifacts.require('UpdatedDummyUsernameRegistrar');
|
||||
const Dummy2UsernameRegistrar = artifacts.require('Dummy2UsernameRegistrar');
|
||||
const UpdatedDummy2UsernameRegistrar = artifacts.require('UpdatedDummy2UsernameRegistrar');
|
||||
const SlashMechanism = artifacts.require('SlashMechanism');
|
||||
const Dummy2SlashMechanism = artifacts.require('Dummy2SlashMechanism');
|
||||
|
||||
contract('UsernameRegistrar', function () {
|
||||
|
||||
@ -155,9 +160,9 @@ contract('UsernameRegistrar', function () {
|
||||
await utils.increaseTime(1000)
|
||||
const initialPrice = 100
|
||||
const resultSetRegistryPrice = await UsernameRegistrar.methods.activate(initialPrice).send({from: accountsArr[0]});
|
||||
assert.equal(resultSetRegistryPrice.events.RegistryPrice.returnValues.price, initialPrice, "event RegistryPrice wrong price");
|
||||
assert.equal(await UsernameRegistrar.methods.state().call(), 1, "Wrong registry state")
|
||||
assert.equal(await UsernameRegistrar.methods.price().call(), initialPrice, "Wrong registry price")
|
||||
assert.equal(+resultSetRegistryPrice.events.RegistryPrice.returnValues.price, initialPrice, "event RegistryPrice wrong price");
|
||||
assert.equal(+await UsernameRegistrar.methods.state().call(), 1, "Wrong registry state")
|
||||
assert.equal(+await UsernameRegistrar.methods.price().call(), initialPrice, "Wrong registry price")
|
||||
});
|
||||
});
|
||||
|
||||
@ -165,9 +170,9 @@ contract('UsernameRegistrar', function () {
|
||||
it('should change registry price', async () => {
|
||||
const newPrice = registry.price;
|
||||
const resultUpdateRegistryPrice = await UsernameRegistrar.methods.updateRegistryPrice(newPrice).send({from: accountsArr[0]});
|
||||
assert.equal(resultUpdateRegistryPrice.events.RegistryPrice.returnValues.price, registry.price, "event RegistryPrice wrong price");
|
||||
assert.equal(await UsernameRegistrar.methods.state().call(), 1, "Wrong registry state")
|
||||
assert.equal(await UsernameRegistrar.methods.price().call(), newPrice, "Wrong registry price")
|
||||
assert.equal(+resultUpdateRegistryPrice.events.RegistryPrice.returnValues.price, registry.price, "event RegistryPrice wrong price");
|
||||
assert.equal(+await UsernameRegistrar.methods.state().call(), 1, "Wrong registry state")
|
||||
assert.equal(+await UsernameRegistrar.methods.price().call(), newPrice, "Wrong registry price")
|
||||
});
|
||||
});
|
||||
|
||||
@ -177,10 +182,10 @@ contract('UsernameRegistrar', function () {
|
||||
const username = 'erin';
|
||||
const usernameHash = namehash.hash(username + '.' + registry.registry);
|
||||
const label = web3Utils.sha3(username);
|
||||
const registryPrice = await UsernameRegistrar.methods.getPrice().call()
|
||||
const registryPrice = +await UsernameRegistrar.methods.getPrice().call()
|
||||
await TestToken.methods.mint(registry.price).send({from: registrant});
|
||||
const initialRegistrantBalance = await TestToken.methods.balanceOf(registrant).call();
|
||||
const initialRegistryBalance = await TestToken.methods.balanceOf(UsernameRegistrar.address).call();
|
||||
const initialRegistrantBalance = +await TestToken.methods.balanceOf(registrant).call();
|
||||
const initialRegistryBalance = +await TestToken.methods.balanceOf(UsernameRegistrar.address).call();
|
||||
await TestToken.methods.approve(UsernameRegistrar.address, registry.price).send({from: registrant});
|
||||
const resultRegister = await UsernameRegistrar.methods.register(
|
||||
web3Utils.sha3(username),
|
||||
@ -191,7 +196,7 @@ contract('UsernameRegistrar', function () {
|
||||
assert.equal(resultRegister.events['0'].raw.topics[0], web3Utils.sha3("Transfer(address,address,uint256)"), "Wrong Event");
|
||||
assert.equal(utils.eventAddress(resultRegister.events['0'].raw.topics[1]), registrant, "Wrong Transfer from");
|
||||
assert.equal(utils.eventAddress(resultRegister.events['0'].raw.topics[2]), UsernameRegistrar.address, "Wrong transfer to");
|
||||
assert.equal(resultRegister.events['0'].raw.data, registry.price, "Wrong transfer value");
|
||||
assert.equal(+resultRegister.events['0'].raw.data, registry.price, "Wrong transfer value");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[0], web3Utils.sha3("NewOwner(bytes32,bytes32,address)"), "Wrong Event");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[1], registry.namehash, "Wrong Node");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[2], label, "Wrong Label");
|
||||
@ -200,10 +205,10 @@ contract('UsernameRegistrar', function () {
|
||||
assert.equal(resultRegister.events.UsernameOwner.returnValues.nameHash, usernameHash, "event UsernameOwner usernameHash mismatch");
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant, "ENSRegistry owner mismatch");
|
||||
assert.equal(await ENSRegistry.methods.resolver(usernameHash).call(), utils.zeroAddress, "Resolver wrongly defined");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountBalance(label).call(), registryPrice, "Registry username account balance wrong");
|
||||
assert.equal(+await UsernameRegistrar.methods.getAccountBalance(label).call(), registryPrice, "Registry username account balance wrong");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountOwner(label).call(), registrant, "Account owner mismatch");
|
||||
assert.equal(await TestToken.methods.balanceOf(registrant).call(), +initialRegistrantBalance-registryPrice, "User final balance wrong")
|
||||
assert.equal(await TestToken.methods.balanceOf(UsernameRegistrar.address).call(), (+initialRegistryBalance)+(+registry.price), "Registry final balance wrong")
|
||||
assert.equal(+await TestToken.methods.balanceOf(registrant).call(), +initialRegistrantBalance-registryPrice, "User final balance wrong")
|
||||
assert.equal(+await TestToken.methods.balanceOf(UsernameRegistrar.address).call(), (+initialRegistryBalance)+(+registry.price), "Registry final balance wrong")
|
||||
});
|
||||
it('should register username only resolveing address ', async () => {
|
||||
const registrant = accountsArr[2];
|
||||
@ -222,7 +227,7 @@ contract('UsernameRegistrar', function () {
|
||||
assert.equal(resultRegister.events['0'].raw.topics[0], web3Utils.sha3("Transfer(address,address,uint256)"), "Wrong Event");
|
||||
assert.equal(utils.eventAddress(resultRegister.events['0'].raw.topics[1]), registrant, "Wrong Transfer from");
|
||||
assert.equal(utils.eventAddress(resultRegister.events['0'].raw.topics[2]), UsernameRegistrar.address, "Wrong transfer to");
|
||||
assert.equal(resultRegister.events['0'].raw.data, registry.price, "Wrong transfer value");
|
||||
assert.equal(+resultRegister.events['0'].raw.data, registry.price, "Wrong transfer value");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[0], web3Utils.sha3("NewOwner(bytes32,bytes32,address)"), "Wrong Event");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[1], registry.namehash, "Wrong Node");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[2], label, "Wrong Label");
|
||||
@ -240,7 +245,7 @@ contract('UsernameRegistrar', function () {
|
||||
assert.equal(resultRegister.events.UsernameOwner.returnValues.nameHash, usernameHash, "event UsernameOwner usernameHash mismatch");
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant, "ENSRegistry owner mismatch");
|
||||
assert.equal(await ENSRegistry.methods.resolver(usernameHash).call(), PublicResolver.address, "Resolver wrongly defined");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(+await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountOwner(label).call(), registrant, "Account owner mismatch");
|
||||
assert.equal(await PublicResolver.methods.addr(usernameHash).call(), registrant, "Resolved address not set");
|
||||
const resolverPubKey = await PublicResolver.methods.pubkey(usernameHash).call();
|
||||
@ -265,7 +270,7 @@ contract('UsernameRegistrar', function () {
|
||||
assert.equal(resultRegister.events['0'].raw.topics[0], web3Utils.sha3("Transfer(address,address,uint256)"), "Wrong Event");
|
||||
assert.equal(utils.eventAddress(resultRegister.events['0'].raw.topics[1]), registrant, "Wrong Transfer from");
|
||||
assert.equal(utils.eventAddress(resultRegister.events['0'].raw.topics[2]), UsernameRegistrar.address, "Wrong transfer to");
|
||||
assert.equal(resultRegister.events['0'].raw.data, registry.price, "Wrong transfer value");
|
||||
assert.equal(+resultRegister.events['0'].raw.data, registry.price, "Wrong transfer value");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[0], web3Utils.sha3("NewOwner(bytes32,bytes32,address)"), "Wrong Event");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[1], registry.namehash, "Wrong Node");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[2], label, "Wrong Label");
|
||||
@ -283,7 +288,7 @@ contract('UsernameRegistrar', function () {
|
||||
assert.equal(resultRegister.events.UsernameOwner.returnValues.nameHash, usernameHash, "event UsernameOwner usernameHash mismatch");
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant, "ENSRegistry owner mismatch");
|
||||
assert.equal(await ENSRegistry.methods.resolver(usernameHash).call(), PublicResolver.address, "Resolver wrongly defined");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(+await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountOwner(label).call(), registrant, "Account owner mismatch");
|
||||
assert.equal(await PublicResolver.methods.addr(usernameHash).call(), utils.zeroAddress, "Resolved address not set");
|
||||
const resolverPubKey = await PublicResolver.methods.pubkey(usernameHash).call();
|
||||
@ -308,7 +313,7 @@ contract('UsernameRegistrar', function () {
|
||||
assert.equal(resultRegister.events['0'].raw.topics[0], web3Utils.sha3("Transfer(address,address,uint256)"), "Wrong Event");
|
||||
assert.equal(utils.eventAddress(resultRegister.events['0'].raw.topics[1]), registrant, "Wrong Transfer from");
|
||||
assert.equal(utils.eventAddress(resultRegister.events['0'].raw.topics[2]), UsernameRegistrar.address, "Wrong transfer to");
|
||||
assert.equal(resultRegister.events['0'].raw.data, registry.price, "Wrong transfer value");
|
||||
assert.equal(+resultRegister.events['0'].raw.data, registry.price, "Wrong transfer value");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[0], web3Utils.sha3("NewOwner(bytes32,bytes32,address)"), "Wrong Event");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[1], registry.namehash, "Wrong Node");
|
||||
assert.equal(resultRegister.events['1'].raw.topics[2], label, "Wrong Label");
|
||||
@ -329,7 +334,7 @@ contract('UsernameRegistrar', function () {
|
||||
assert.equal(resultRegister.events.UsernameOwner.returnValues.nameHash, usernameHash, "event UsernameOwner usernameHash mismatch");
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant, "ENSRegistry owner mismatch");
|
||||
assert.equal(await ENSRegistry.methods.resolver(usernameHash).call(), PublicResolver.address, "Resolver wrongly defined");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(+await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountOwner(label).call(), registrant, "Account owner mismatch");
|
||||
assert.equal(await PublicResolver.methods.addr(usernameHash).call(), registrant, "Resolved address not set");
|
||||
const resolverPubKey = await PublicResolver.methods.pubkey(usernameHash).call();
|
||||
@ -344,10 +349,10 @@ contract('UsernameRegistrar', function () {
|
||||
const username = 'erinauto';
|
||||
const usernameHash = namehash.hash(username + '.' + registry.registry);
|
||||
const label = web3Utils.sha3(username);
|
||||
const registryPrice = await UsernameRegistrar.methods.getPrice().call()
|
||||
const registryPrice = +await UsernameRegistrar.methods.getPrice().call()
|
||||
await TestToken.methods.mint(registry.price).send({from: registrant});
|
||||
const initialRegistrantBalance = await TestToken.methods.balanceOf(registrant).call();
|
||||
const initialRegistryBalance = await TestToken.methods.balanceOf(UsernameRegistrar.address).call();
|
||||
const initialRegistrantBalance = +await TestToken.methods.balanceOf(registrant).call();
|
||||
const initialRegistryBalance = +await TestToken.methods.balanceOf(UsernameRegistrar.address).call();
|
||||
|
||||
const registerCall = UsernameRegistrar.methods.register(
|
||||
web3Utils.sha3(username),
|
||||
@ -359,10 +364,10 @@ contract('UsernameRegistrar', function () {
|
||||
// TODO: check events
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant, "ENSRegistry owner mismatch");
|
||||
assert.equal(await ENSRegistry.methods.resolver(usernameHash).call(), utils.zeroAddress, "Resolver wrongly defined");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountBalance(label).call(), registryPrice, "Registry username account balance wrong");
|
||||
assert.equal(+await UsernameRegistrar.methods.getAccountBalance(label).call(), registryPrice, "Registry username account balance wrong");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountOwner(label).call(), registrant, "Account owner mismatch");
|
||||
assert.equal(await TestToken.methods.balanceOf(registrant).call(), +initialRegistrantBalance-registryPrice, "User final balance wrong")
|
||||
assert.equal(await TestToken.methods.balanceOf(UsernameRegistrar.address).call(), (+initialRegistryBalance)+(+registry.price), "Registry final balance wrong")
|
||||
assert.equal(+await TestToken.methods.balanceOf(registrant).call(), +initialRegistrantBalance-registryPrice, "User final balance wrong")
|
||||
assert.equal(+await TestToken.methods.balanceOf(UsernameRegistrar.address).call(), (+initialRegistryBalance)+(+registry.price), "Registry final balance wrong")
|
||||
});
|
||||
it('should register username only resolving address ', async () => {
|
||||
const registrant = accountsArr[2];
|
||||
@ -383,7 +388,7 @@ contract('UsernameRegistrar', function () {
|
||||
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant, "ENSRegistry owner mismatch");
|
||||
assert.equal(await ENSRegistry.methods.resolver(usernameHash).call(), PublicResolver.address, "Resolver wrongly defined");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(+await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountOwner(label).call(), registrant, "Account owner mismatch");
|
||||
assert.equal(await PublicResolver.methods.addr(usernameHash).call(), registrant, "Resolved address not set");
|
||||
const resolverPubKey = await PublicResolver.methods.pubkey(usernameHash).call();
|
||||
@ -410,7 +415,7 @@ contract('UsernameRegistrar', function () {
|
||||
// TODO: check events
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant, "ENSRegistry owner mismatch");
|
||||
assert.equal(await ENSRegistry.methods.resolver(usernameHash).call(), PublicResolver.address, "Resolver wrongly defined");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(+await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountOwner(label).call(), registrant, "Account owner mismatch");
|
||||
assert.equal(await PublicResolver.methods.addr(usernameHash).call(), utils.zeroAddress, "Resolved address not set");
|
||||
const resolverPubKey = await PublicResolver.methods.pubkey(usernameHash).call();
|
||||
@ -436,7 +441,7 @@ contract('UsernameRegistrar', function () {
|
||||
// TODO: check events
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant, "ENSRegistry owner mismatch");
|
||||
assert.equal(await ENSRegistry.methods.resolver(usernameHash).call(), PublicResolver.address, "Resolver wrongly defined");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(+await UsernameRegistrar.methods.getAccountBalance(label).call(), registry.price, "Wrong account balance");
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountOwner(label).call(), registrant, "Account owner mismatch");
|
||||
assert.equal(await PublicResolver.methods.addr(usernameHash).call(), registrant, "Resolved address not set");
|
||||
const resolverPubKey = await PublicResolver.methods.pubkey(usernameHash).call();
|
||||
@ -480,21 +485,21 @@ contract('UsernameRegistrar', function () {
|
||||
utils.zeroBytes32,
|
||||
utils.zeroBytes32
|
||||
).send({from: registrant});
|
||||
const releaseDelay = await UsernameRegistrar.methods.releaseDelay().call();
|
||||
const releaseDelay = +await UsernameRegistrar.methods.releaseDelay().call();
|
||||
await utils.increaseTime(releaseDelay)
|
||||
await utils.increaseTime(1000)
|
||||
const initialAccountBalance = await UsernameRegistrar.methods.getAccountBalance(label).call();
|
||||
const initialRegistrantBalance = await TestToken.methods.balanceOf(registrant).call();
|
||||
const initialRegistryBalance = await TestToken.methods.balanceOf(UsernameRegistrar.address).call();
|
||||
const initialAccountBalance = +await UsernameRegistrar.methods.getAccountBalance(label).call();
|
||||
const initialRegistrantBalance = +await TestToken.methods.balanceOf(registrant).call();
|
||||
const initialRegistryBalance = +await TestToken.methods.balanceOf(UsernameRegistrar.address).call();
|
||||
await utils.increaseTime(1000)
|
||||
const resultRelease = await UsernameRegistrar.methods.release(
|
||||
web3Utils.sha3(username),
|
||||
|
||||
).send({from: registrant});
|
||||
//TODO: check events
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountBalance(label).call(), 0, "Final balance didnt zeroed");
|
||||
assert.equal(await TestToken.methods.balanceOf(registrant).call(), (+initialRegistrantBalance)+(+initialAccountBalance), "Releaser token balance didnt increase")
|
||||
assert.equal(await TestToken.methods.balanceOf(UsernameRegistrar.address).call(), (+initialRegistryBalance)-(+initialAccountBalance), "Registry token balance didnt decrease")
|
||||
assert.equal(+await UsernameRegistrar.methods.getAccountBalance(label).call(), 0, "Final balance didnt zeroed");
|
||||
assert.equal(+await TestToken.methods.balanceOf(registrant).call(), (+initialRegistrantBalance)+(+initialAccountBalance), "Releaser token balance didnt increase")
|
||||
assert.equal(+await TestToken.methods.balanceOf(UsernameRegistrar.address).call(), (+initialRegistryBalance)-(+initialAccountBalance), "Registry token balance didnt decrease")
|
||||
});
|
||||
it('should release transfered username', async () => {
|
||||
let registrant = accountsArr[7];
|
||||
@ -511,20 +516,20 @@ contract('UsernameRegistrar', function () {
|
||||
utils.zeroBytes32
|
||||
).send({from: registrant});
|
||||
await ENSRegistry.methods.setOwner(usernameHash, newOwner).send({from: registrant});
|
||||
let releaseDelay = await UsernameRegistrar.methods.releaseDelay().call();
|
||||
let releaseDelay = +await UsernameRegistrar.methods.releaseDelay().call();
|
||||
await utils.increaseTime(releaseDelay)
|
||||
await utils.increaseTime(1000)
|
||||
let initialAccountBalance = await UsernameRegistrar.methods.getAccountBalance(label).call();
|
||||
let initialRegistrantBalance = await TestToken.methods.balanceOf(newOwner).call();
|
||||
let initialRegistryBalance = await TestToken.methods.balanceOf(UsernameRegistrar.address).call();
|
||||
let initialAccountBalance = +await UsernameRegistrar.methods.getAccountBalance(label).call();
|
||||
let initialRegistrantBalance = +await TestToken.methods.balanceOf(newOwner).call();
|
||||
let initialRegistryBalance = +await TestToken.methods.balanceOf(UsernameRegistrar.address).call();
|
||||
await utils.increaseTime(1000)
|
||||
let resultRelease = await UsernameRegistrar.methods.release(
|
||||
label
|
||||
).send({from: newOwner});
|
||||
//TODO: check events
|
||||
assert.equal(await UsernameRegistrar.methods.getAccountBalance(label).call(), 0, "Final balance didnt zeroed");
|
||||
assert.equal(await TestToken.methods.balanceOf(newOwner).call(), (+initialRegistrantBalance)+(+initialAccountBalance), "New owner token balance didnt increase")
|
||||
assert.equal(await TestToken.methods.balanceOf(UsernameRegistrar.address).call(), (+initialRegistryBalance)-(+initialAccountBalance), "Registry token balance didnt decrease")
|
||||
assert.equal(+await UsernameRegistrar.methods.getAccountBalance(label).call(), 0, "Final balance didnt zeroed");
|
||||
assert.equal(+await TestToken.methods.balanceOf(newOwner).call(), (+initialRegistrantBalance)+(+initialAccountBalance), "New owner token balance didnt increase")
|
||||
assert.equal(+await TestToken.methods.balanceOf(UsernameRegistrar.address).call(), (+initialRegistryBalance)-(+initialAccountBalance), "Registry token balance didnt decrease")
|
||||
});
|
||||
it('should release moved username account balance by owner', async () => {
|
||||
const registrant = accountsArr[5];
|
||||
@ -541,9 +546,9 @@ contract('UsernameRegistrar', function () {
|
||||
utils.zeroBytes32,
|
||||
utils.zeroBytes32
|
||||
).send({from: registrant});
|
||||
let initialAccountBalance = await DummyUsernameRegistrar.methods.getAccountBalance(label).call();
|
||||
const initialRegistrantBalance = await TestToken.methods.balanceOf(registrant).call();
|
||||
const initialRegistryBalance = await TestToken.methods.balanceOf(DummyUsernameRegistrar.address).call();
|
||||
let initialAccountBalance = +await DummyUsernameRegistrar.methods.getAccountBalance(label).call();
|
||||
const initialRegistrantBalance = +await TestToken.methods.balanceOf(registrant).call();
|
||||
const initialRegistryBalance = +await TestToken.methods.balanceOf(DummyUsernameRegistrar.address).call();
|
||||
await DummyUsernameRegistrar.methods.moveRegistry(UpdatedDummyUsernameRegistrar.address).send();
|
||||
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant, "ENSRegistry owner mismatch");
|
||||
@ -554,8 +559,8 @@ contract('UsernameRegistrar', function () {
|
||||
label
|
||||
).send({from: registrant});
|
||||
//TODO: verify events
|
||||
assert.equal(await TestToken.methods.balanceOf(registrant).call(), (+initialRegistrantBalance)+(+initialAccountBalance), "New owner token balance didnt increase")
|
||||
assert.equal(await TestToken.methods.balanceOf(DummyUsernameRegistrar.address).call(), (+initialRegistryBalance)-(+initialAccountBalance), "Registry token balance didnt decrease")
|
||||
assert.equal(+await TestToken.methods.balanceOf(registrant).call(), (+initialRegistrantBalance)+(+initialAccountBalance), "New owner token balance didnt increase")
|
||||
assert.equal(+await TestToken.methods.balanceOf(DummyUsernameRegistrar.address).call(), (+initialRegistryBalance)-(+initialAccountBalance), "Registry token balance didnt decrease")
|
||||
assert.equal(await ENSRegistry.methods.resolver(usernameHash).call(), utils.zeroAddress, "Resolver not undefined");
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), utils.zeroAddress, "Owner not removed");
|
||||
//We are not cleaning PublicResolver or any resolver, so the value should remain the same.
|
||||
@ -605,14 +610,13 @@ contract('UsernameRegistrar', function () {
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(20000)
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
assert.notEqual(await UsernameRegistrar.methods.getCreationTime(label).call(), 0);
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(web3Utils.sha3(username)).call();
|
||||
assert.notEqual(+await UsernameRegistrar.methods.getCreationTime(label).call(), 0);
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
await UsernameRegistrar.methods.slashInvalidUsername(username, 4, reserveSecret).send()
|
||||
const secret = web3Utils.soliditySha3(username, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
await SlashMechanism.methods.slashInvalidUsername(username, 4, reserveSecret).send()
|
||||
//TODO: check events
|
||||
assert.equal(await UsernameRegistrar.methods.getCreationTime(label).call(), 0);
|
||||
assert.equal(+await UsernameRegistrar.methods.getCreationTime(label).call(), 0);
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), utils.zeroAddress);
|
||||
});
|
||||
it('should not slash valid username', async () => {
|
||||
@ -628,13 +632,12 @@ contract('UsernameRegistrar', function () {
|
||||
utils.zeroBytes32
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(20000)
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(web3Utils.sha3(username)).call();
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
const secret = web3Utils.soliditySha3(username, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
let failed;
|
||||
try{
|
||||
await UsernameRegistrar.methods.slashInvalidUsername(username, 4, reserveSecret).send()
|
||||
await SlashMechanism.methods.slashInvalidUsername(username, 4, reserveSecret).send()
|
||||
failed = false;
|
||||
} catch(e){
|
||||
failed = true;
|
||||
@ -658,13 +661,12 @@ contract('UsernameRegistrar', function () {
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(20000)
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(web3Utils.sha3(username)).call();
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
const secret = web3Utils.soliditySha3(username, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
let failed;
|
||||
try{
|
||||
await UsernameRegistrar.methods.slashReservedUsername(username, merkleTree.getHexProof(ReservedUsernames[0]), reserveSecret).send()
|
||||
await SlashMechanism.methods.slashReservedUsername(username, merkleTree.getHexProof(ReservedUsernames[0]), reserveSecret).send()
|
||||
failed = false;
|
||||
} catch(e){
|
||||
failed = true;
|
||||
@ -685,13 +687,12 @@ contract('UsernameRegistrar', function () {
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(20000)
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(web3Utils.sha3(username)).call();
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
const secret = web3Utils.soliditySha3(username, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
let failed;
|
||||
try{
|
||||
await UsernameRegistrar.methods.slashReservedUsername(username, merkleTree.getHexProof(ReservedUsernames[1]), reserveSecret).send()
|
||||
await SlashMechanism.methods.slashReservedUsername(username, merkleTree.getHexProof(ReservedUsernames[1]), reserveSecret).send()
|
||||
failed = false;
|
||||
} catch(e){
|
||||
failed = true;
|
||||
@ -712,11 +713,10 @@ contract('UsernameRegistrar', function () {
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(20000)
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(web3Utils.sha3(username)).call();
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
result = await UsernameRegistrar.methods.slashReservedUsername(username, merkleTree.getHexProof(username), reserveSecret).send()
|
||||
const secret = web3Utils.soliditySha3(username, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
await SlashMechanism.methods.slashReservedUsername(username, merkleTree.getHexProof(username), reserveSecret).send()
|
||||
//TODO: check events
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), utils.zeroAddress);
|
||||
});
|
||||
@ -736,13 +736,13 @@ contract('UsernameRegistrar', function () {
|
||||
utils.zeroBytes32
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(1000)
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(web3Utils.sha3(username)).call();
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
const secret = web3Utils.soliditySha3(username, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
let failed;
|
||||
try{
|
||||
await UsernameRegistrar.methods.slashSmallUsername(username).send()
|
||||
await SlashMechanism.methods.slashSmallUsername(username).send()
|
||||
failed = false;
|
||||
} catch(e){
|
||||
failed = true;
|
||||
@ -764,11 +764,10 @@ contract('UsernameRegistrar', function () {
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(20000)
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(web3Utils.sha3(username)).call();
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
result = await UsernameRegistrar.methods.slashSmallUsername(username, reserveSecret).send()
|
||||
const secret = web3Utils.soliditySha3(username, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
result = await SlashMechanism.methods.slashSmallUsername(username, reserveSecret).send()
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), utils.zeroAddress);
|
||||
});
|
||||
});
|
||||
@ -789,11 +788,10 @@ contract('UsernameRegistrar', function () {
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(1000)
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(userlabelHash).call();
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
result = await UsernameRegistrar.methods.slashAddressLikeUsername(username, reserveSecret).send()
|
||||
const secret = web3Utils.soliditySha3({value: username, type: "string"}, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
result = await SlashMechanism.methods.slashAddressLikeUsername(username, reserveSecret).send()
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), utils.zeroAddress);
|
||||
});
|
||||
it('should not slash username that starts with 0x but is smaller then 12', async () => {
|
||||
@ -810,13 +808,13 @@ contract('UsernameRegistrar', function () {
|
||||
utils.zeroBytes32
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(20000)
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(userlabelHash).call();
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
const secret = web3Utils.soliditySha3({value: username, type: "string"}, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
let failed;
|
||||
try{
|
||||
result = await UsernameRegistrar.methods.slashAddressLikeUsername(username, reserveSecret).send()
|
||||
await SlashMechanism.methods.slashAddressLikeUsername(username, reserveSecret).send()
|
||||
failed = false;
|
||||
} catch(e){
|
||||
failed = true;
|
||||
@ -837,13 +835,13 @@ contract('UsernameRegistrar', function () {
|
||||
utils.zeroBytes32
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(20000)
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(userlabelHash).call();
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
const secret = web3Utils.soliditySha3({value: username, type: "string"}, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
let failed;
|
||||
try{
|
||||
await UsernameRegistrar.methods.slashAddressLikeUsername(username, reserveSecret).send()
|
||||
await SlashMechanism.methods.slashAddressLikeUsername(username, reserveSecret).send()
|
||||
failed = false;
|
||||
} catch(e){
|
||||
failed = true;
|
||||
@ -864,13 +862,13 @@ contract('UsernameRegistrar', function () {
|
||||
utils.zeroBytes32
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(20000)
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(userlabelHash).call();
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send();
|
||||
const secret = web3Utils.soliditySha3({value: username, type: "string"}, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send();
|
||||
let failed;
|
||||
try{
|
||||
await UsernameRegistrar.methods.slashAddressLikeUsername(username, reserveSecret).send()
|
||||
await SlashMechanism.methods.slashAddressLikeUsername(username, reserveSecret).send()
|
||||
failed = false;
|
||||
} catch(e){
|
||||
failed = true;
|
||||
@ -896,18 +894,17 @@ contract('UsernameRegistrar', function () {
|
||||
await utils.increaseTime(20000)
|
||||
const partReward = await UsernameRegistrar.methods.getSlashRewardPart(label).call();
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const initialSlasherBalance = await TestToken.methods.balanceOf(slasher).call();
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(label).call();
|
||||
const initialSlasherBalance = +await TestToken.methods.balanceOf(slasher).call();
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send({from: slasher});
|
||||
await UsernameRegistrar.methods.slashSmallUsername(username, reserveSecret).send({from: slasher})
|
||||
const secret = web3Utils.soliditySha3(username, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send({from: slasher});
|
||||
await SlashMechanism.methods.slashSmallUsername(username, reserveSecret).send({from: slasher})
|
||||
//TODO: check events
|
||||
assert.equal(await TestToken.methods.balanceOf(slasher).call(), (+initialSlasherBalance)+((+partReward)*2));
|
||||
assert.equal(+await TestToken.methods.balanceOf(slasher).call(), (+initialSlasherBalance)+((+partReward)*2));
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), utils.zeroAddress);
|
||||
});
|
||||
|
||||
it('should slash a username of a not migrated subnode that became unallowed', async () => {
|
||||
it('should return funds of slashing when changed rules', async () => {
|
||||
const registrant = accountsArr[5];
|
||||
const notRegistrant = accountsArr[6];
|
||||
|
||||
@ -925,20 +922,19 @@ contract('UsernameRegistrar', function () {
|
||||
).send({from: registrant});
|
||||
await utils.increaseTime(20000)
|
||||
let initialAccountBalance = await Dummy2UsernameRegistrar.methods.getAccountBalance(label).call();
|
||||
const initialRegistrantBalance = await TestToken.methods.balanceOf(registrant).call();
|
||||
const initialRegistryBalance = await TestToken.methods.balanceOf(Dummy2UsernameRegistrar.address).call();
|
||||
const initialRegistrantBalance = +await TestToken.methods.balanceOf(registrant).call();
|
||||
const initialRegistryBalance = +await TestToken.methods.balanceOf(Dummy2UsernameRegistrar.address).call();
|
||||
|
||||
|
||||
await Dummy2UsernameRegistrar.methods.moveRegistry(UpdatedDummy2UsernameRegistrar.address).send();
|
||||
await Dummy2UsernameRegistrar.methods.setSlashMechanism(SlashMechanism.address).send();
|
||||
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant, "ENSRegistry owner mismatch");
|
||||
assert.equal(await ENSRegistry.methods.resolver(usernameHash).call(), PublicResolver.address, "Resolver wrongly defined");
|
||||
assert.equal(await PublicResolver.methods.addr(usernameHash).call(), registrant, "Resolved address not set");
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(label).call();
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send({from: notRegistrant});
|
||||
const resultRelease = await UpdatedDummy2UsernameRegistrar.methods.slashReservedUsername(
|
||||
const secret = web3Utils.soliditySha3(username, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(Dummy2UsernameRegistrar.address, secret).send({from: notRegistrant});
|
||||
await SlashMechanism.methods.slashReservedUsername(
|
||||
username,
|
||||
merkleTree.getHexProof(username),
|
||||
reserveSecret
|
||||
@ -970,14 +966,13 @@ contract('UsernameRegistrar', function () {
|
||||
await utils.increaseTime(20000)
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const partReward = await UsernameRegistrar.methods.getSlashRewardPart(label).call();
|
||||
const initialSlashReserverBalance = await TestToken.methods.balanceOf(slashReserverCaller).call();
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(label).call();
|
||||
const initialSlashReserverBalance = +await TestToken.methods.balanceOf(slashReserverCaller).call();
|
||||
const reserveSecret = 1337;
|
||||
const secret = web3Utils.soliditySha3(usernameHash, creationTime, reserveSecret);
|
||||
await UsernameRegistrar.methods.reserveSlash(secret).send({from: slashReserverCaller});
|
||||
await UsernameRegistrar.methods.slashSmallUsername(username, reserveSecret).send({from: slashReserverCaller})
|
||||
const secret = web3Utils.soliditySha3(username, reserveSecret);
|
||||
await SlashMechanism.methods.reserveSlash(UsernameRegistrar.address, secret).send({from: slashReserverCaller});
|
||||
await SlashMechanism.methods.slashSmallUsername(username, reserveSecret).send({from: slashReserverCaller})
|
||||
//TODO: check events
|
||||
assert.equal(await TestToken.methods.balanceOf(slashReserverCaller).call(), (+initialSlashReserverBalance)+(+partReward*2));
|
||||
assert.equal(+await TestToken.methods.balanceOf(slashReserverCaller).call(), (+initialSlashReserverBalance)+(+partReward*2));
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), utils.zeroAddress);
|
||||
});
|
||||
});
|
||||
@ -1012,7 +1007,7 @@ describe('eraseNode(bytes32[])', function() {
|
||||
utils.zeroBytes32
|
||||
).send({from: registrant});
|
||||
assert.equal(await ENSRegistry.methods.owner(usernameHash).call(), registrant);
|
||||
const releaseDelay = await UsernameRegistrar.methods.releaseDelay().call();
|
||||
const releaseDelay = +await UsernameRegistrar.methods.releaseDelay().call();
|
||||
await utils.increaseTime(releaseDelay)
|
||||
await utils.increaseTime(1000)
|
||||
await utils.increaseTime(1000)
|
||||
@ -1055,7 +1050,7 @@ describe('eraseNode(bytes32[])', function() {
|
||||
const result = await UsernameRegistrar.methods.moveRegistry(UpdatedUsernameRegistrar.address).send();
|
||||
//TODO: check events
|
||||
assert.equal(await ENSRegistry.methods.owner(registry.namehash).call(), UpdatedUsernameRegistrar.address, "registry ownership not moved correctly")
|
||||
assert.equal(await UpdatedUsernameRegistrar.methods.getPrice().call(), registry.price, "updated registry didnt migrated price")
|
||||
assert.equal(+await UpdatedUsernameRegistrar.methods.getPrice().call(), registry.price, "updated registry didnt migrated price")
|
||||
});
|
||||
});
|
||||
|
||||
@ -1066,18 +1061,18 @@ describe('eraseNode(bytes32[])', function() {
|
||||
const usernameHash = namehash.hash(username + '.' + registry.registry);
|
||||
const label = web3Utils.sha3(username);
|
||||
|
||||
const accountBalance = await UsernameRegistrar.methods.getAccountBalance(label).call()
|
||||
const accountBalance = +await UsernameRegistrar.methods.getAccountBalance(label).call()
|
||||
assert.notEqual(accountBalance, 0);
|
||||
const initialRegistryBalance = await TestToken.methods.balanceOf(UsernameRegistrar.address).call();
|
||||
const initialUpdatedRegistryBalance = await TestToken.methods.balanceOf(UpdatedUsernameRegistrar.address).call();
|
||||
const creationTime = await UsernameRegistrar.methods.getCreationTime(label).call();
|
||||
const initialRegistryBalance = +await TestToken.methods.balanceOf(UsernameRegistrar.address).call();
|
||||
const initialUpdatedRegistryBalance = +await TestToken.methods.balanceOf(UpdatedUsernameRegistrar.address).call();
|
||||
const creationTime = +await UsernameRegistrar.methods.getCreationTime(label).call();
|
||||
assert.notEqual(creationTime, 0);
|
||||
assert.equal(await UpdatedUsernameRegistrar.methods.getCreationTime(label).call(), 0);
|
||||
assert.equal(+await UpdatedUsernameRegistrar.methods.getCreationTime(label).call(), 0);
|
||||
const result = await UsernameRegistrar.methods.moveAccount(label, UpdatedUsernameRegistrar.address).send({from: registrant});
|
||||
assert.equal(await UsernameRegistrar.methods.getCreationTime(label).call(), 0);
|
||||
assert.equal(await UpdatedUsernameRegistrar.methods.getCreationTime(label).call(), creationTime);
|
||||
assert.equal(await TestToken.methods.balanceOf(UsernameRegistrar.address).call(), (+initialRegistryBalance)-(+accountBalance))
|
||||
assert.equal(await TestToken.methods.balanceOf(UpdatedUsernameRegistrar.address).call(), (+initialUpdatedRegistryBalance)+(+accountBalance))
|
||||
assert.equal(+await UsernameRegistrar.methods.getCreationTime(label).call(), 0);
|
||||
assert.equal(+await UpdatedUsernameRegistrar.methods.getCreationTime(label).call(), creationTime);
|
||||
assert.equal(+await TestToken.methods.balanceOf(UsernameRegistrar.address).call(), (+initialRegistryBalance)-(+accountBalance))
|
||||
assert.equal(+await TestToken.methods.balanceOf(UpdatedUsernameRegistrar.address).call(), (+initialUpdatedRegistryBalance)+(+accountBalance))
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -212,39 +212,29 @@ function isException(error) {
|
||||
return strError.includes('invalid opcode') || strError.includes('invalid JUMP') || strError.includes('revert');
|
||||
}
|
||||
|
||||
exports.increaseTime = async (amount) => {
|
||||
return new Promise(function(resolve, reject) {
|
||||
web3.currentProvider.sendAsync(
|
||||
{
|
||||
exports.increaseTime = async (addSeconds) => {
|
||||
const id = Date.now();
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
web3.currentProvider.send({
|
||||
jsonrpc: '2.0',
|
||||
method: 'evm_increaseTime',
|
||||
params: [+amount],
|
||||
id: new Date().getSeconds()
|
||||
},
|
||||
async (error) => {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
return reject(err);
|
||||
}
|
||||
await web3.currentProvider.sendAsync(
|
||||
{
|
||||
params: [addSeconds],
|
||||
id,
|
||||
}, (err1) => {
|
||||
if (err1) return reject(err1);
|
||||
|
||||
web3.currentProvider.send({
|
||||
jsonrpc: '2.0',
|
||||
method: 'evm_mine',
|
||||
params: [],
|
||||
id: new Date().getSeconds()
|
||||
}, (error) => {
|
||||
if (error) {
|
||||
console.log(error);
|
||||
return reject(err);
|
||||
}
|
||||
resolve();
|
||||
}
|
||||
)
|
||||
}
|
||||
)
|
||||
id: id + 1,
|
||||
}, (err2, res) => (err2 ? reject(err2) : resolve(res)));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
exports.generateXY = pub => {
|
||||
const stripped = pub.slice(2);
|
||||
const key = ec.keyFromPublic(stripped, 'hex');
|
||||
|
Loading…
x
Reference in New Issue
Block a user