Skip to content

Commit

Permalink
chore: deploy both GLM and GNT for subgraph, automate networks.json
Browse files Browse the repository at this point in the history
For testnet and mainnet tokens are not deployed.
Tests care only about GLM.
Subgraph assumes existance of two tokens - this is why both are deployed
for 'token' tag, effectively for 'hardhat' and 'localhost' networks.

Please note that src/*.ts files stays, since lots of execution paths
(linters etc) check if this files are there
  • Loading branch information
Pawel Peregud committed Aug 23, 2023
1 parent 46753a4 commit bfda4a0
Show file tree
Hide file tree
Showing 10 changed files with 245 additions and 42 deletions.
Original file line number Diff line number Diff line change
@@ -1,17 +1,26 @@
import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { DeployFunction } from 'hardhat-deploy/types';

import { TOKEN } from '../helpers/constants';
import { GNT, TOKEN } from '../helpers/constants';

// This function needs to be declared this way, otherwise it's not understood by test runner.
// eslint-disable-next-line func-names
const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const { deploy } = hre.deployments;
const { deployer } = await hre.getNamedAccounts();

await deploy(GNT, {
args: [],
autoMine: true,
contract: 'Token',
from: deployer,
log: true,
});

await deploy(TOKEN, {
args: [],
autoMine: true,
contract: 'Token',
from: deployer,
log: true,
});
Expand Down
46 changes: 40 additions & 6 deletions contracts-v1/deploy/9999_after_deployment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,16 @@ import { HardhatRuntimeEnvironment } from 'hardhat/types';
import { DeployFunction } from 'hardhat-deploy/types';

import { GLM_ADDRESS, GNT_ADDRESS } from '../env';
import { WITHDRAWALS_TARGET, EPOCHS, DEPOSITS, PROPOSALS, VAULT, AUTH } from '../helpers/constants';
import {
AUTH,
EPOCHS,
DEPOSITS,
GNT,
PROPOSALS,
TOKEN,
VAULT,
WITHDRAWALS_TARGET,
} from '../helpers/constants';

// This function needs to be declared this way, otherwise it's not understood by test runner.
// eslint-disable-next-line func-names
Expand All @@ -16,10 +25,15 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
const deposits = await hre.ethers.getContract(DEPOSITS);
const proposals = await hre.ethers.getContract(PROPOSALS);
const vault = await hre.ethers.getContract(VAULT);
let gntAddress = GNT_ADDRESS;
let glmAddress = GLM_ADDRESS;

console.log(`GNT_CONTRACT_ADDRESS=${GNT_ADDRESS}`);
console.log(`GLM_CONTRACT_ADDRESS=${GLM_ADDRESS}`);

if (['hardhat', 'localhost'].includes(hre.network.name)) {
gntAddress = (await hre.ethers.getContract(GNT)).address;
glmAddress = (await hre.ethers.getContract(TOKEN)).address;
}
console.log(`GNT_CONTRACT_ADDRESS=${gntAddress}`);
console.log(`GLM_CONTRACT_ADDRESS=${glmAddress}`);
console.log(`DEPOSITS_CONTRACT_ADDRESS=${deposits.address}`);
console.log(`EPOCHS_CONTRACT_ADDRESS=${epochs.address}`);
console.log(`PROPOSALS_CONTRACT_ADDRESS=${proposals.address}`);
Expand All @@ -30,8 +44,8 @@ const func: DeployFunction = async function (hre: HardhatRuntimeEnvironment) {
/* eslint-disable no-console */

const contractAddresses = `
GNT_CONTRACT_ADDRESS=${GNT_ADDRESS}
GLM_CONTRACT_ADDRESS=${GLM_ADDRESS}
GNT_CONTRACT_ADDRESS=${gntAddress}
GLM_CONTRACT_ADDRESS=${glmAddress}
AUTH_CONTRACT_ADDRESS=${auth.address}
DEPOSITS_CONTRACT_ADDRESS=${deposits.address}
EPOCHS_CONTRACT_ADDRESS=${epochs.address}
Expand All @@ -41,6 +55,26 @@ VAULT_CONTRACT_ADDRESS=${vault.address}
`; // Newline is intentional

fs.appendFileSync('deployments/clientEnv', contractAddresses);

if (['localhost'].includes(hre.network.name)) {
// Update networks.json for local (developer's) subgraph instance.
// It's used by both graph-node and entrypoint.sh
const networksFn = '../subgraph/networks.json';
const templateFn = '../subgraph/networks.template.json';
try {
fs.accessSync(networksFn, fs.constants.W_OK);
} catch (_err) {
fs.copyFileSync(templateFn, networksFn);
}

const json = JSON.parse(fs.readFileSync(networksFn).toString());
json.localhost.GNT.address = gntAddress;
json.localhost.GLM.address = glmAddress;
json.localhost.Epochs.address = epochs.address;
json.localhost.Deposits.address = deposits.address;
json.localhost.Vault.address = vault.address;
fs.writeFileSync(networksFn, JSON.stringify(json, null, 2));
}
};

export default func;
Expand Down
3 changes: 2 additions & 1 deletion contracts-v1/helpers/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
export const AUTH = 'Auth';
export const PROPOSALS = 'Proposals';
export const DEPOSITS = 'Deposits';
export const TOKEN = 'Token';
export const TOKEN = 'GLM';
export const GNT = 'GNT';
export const FAUCET = 'TestGLMFaucet';
export const EPOCHS = 'Epochs';
export const WITHDRAWALS_TARGET = 'WithdrawalsTarget';
Expand Down
12 changes: 9 additions & 3 deletions subgraph/entrypoint.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ IPFS_URL=${IPFS_URL:-"http://127.0.0.1:5001"}
LABEL=${VERSION_TAG:-"VM_$HOSTNAME"}
NODE_NAME=${NODE_NAME:-"octant"}
NETWORK_FILE=${NETWORK_FILE:-"./networks.json"}
EPOCHS_ADDRESS=$(cat $NETWORK_FILE | jq -r ".${NETWORK}.Epochs.address")
export GNT_CONTRACT_ADDRESS=$(cat $NETWORK_FILE | jq -r ".${NETWORK}.GNT.address")
export GLM_CONTRACT_ADDRESS=$(cat $NETWORK_FILE | jq -r ".${NETWORK}.GLM.address")
export EPOCHS_CONTRACT_ADDRESS=$(cat $NETWORK_FILE | jq -r ".${NETWORK}.Epochs.address")

echo "Node name: $NODE_NAME"
echo "Network: $NETWORK"
Expand All @@ -17,8 +19,12 @@ echo "Subgraph URL: $SUBGRAPH_URL"
echo "IPFS URL: $IPFS_URL"
echo "EPOCHS addr: $EPOCHS_ADDRESS"
echo
echo "Replace hardcoded contract address"
sed -i'' -E "s/Address.fromString\(.+\)/Address.fromString\('$EPOCHS_ADDRESS')/g" src/epochs.ts
echo "Replace hardcoded contract addresses"
for i in src/*template*; do
echo "Replacing in $i"
F=$(echo $i | sed 's/template\.//')
envsubst < $i > $F
done
echo "Code generation"
npx graph codegen
echo "Build graph"
Expand Down
69 changes: 41 additions & 28 deletions subgraph/networks.template.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,43 @@
{
"sepolia": {
"Deposits": {
"address": "0x044465B505aeE0B790b180750E263e3F83a682e8",
"startBlock": 3771656
},
"Epochs": {
"address": "0x86A032e5e5bEaaEB8eb0F625bEB5426D8B526719",
"startBlock": 3771656
},
"Vault": {
"address": "0xd3C9777a8cafE46583B5425C10196503c4428ddC",
"startBlock": 3771656
}
},
"localhost": {
"Deposits": {
"address": "0x044465B505aeE0B790b180750E263e3F83a682e8",
"startBlock": 3771656
},
"Epochs": {
"address": "0x86A032e5e5bEaaEB8eb0F625bEB5426D8B526719",
"startBlock": 3771656
},
"Vault": {
"address": "0xd3C9777a8cafE46583B5425C10196503c4428ddC",
"startBlock": 3771656
}
}
"localhost" : {
"Deposits" : {
"address" : "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9"
},
"Epochs" : {
"address" : "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0"
},
"GLM" : {
"address" : "0x7DD9c5Cba05E151C895FDe1CF355C9A1D5DA6429"
},
"GNT" : {
"address" : "0xa74476443119A942dE498590Fe1f2454d7D4aC0d"
},
"Vault" : {
"address" : "0xa513E6E4b8f2a923D98304ec87F64353C4D5C853"
}
},
"mainnet" : {
"GLM" : {
"address" : "0x7DD9c5Cba05E151C895FDe1CF355C9A1D5DA6429"
},
"GNT" : {
"address" : "0xa74476443119A942dE498590Fe1f2454d7D4aC0d"
}
},
"sepolia" : {
"Deposits" : {
"address" : "0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9",
"startBlock" : 8415400
},
"Epochs" : {
"address" : "0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0",
"startBlock" : 8415400
},
"GLM" : {
"address" : "0x71432DD1ae7DB41706ee6a22148446087BdD0906"
},
"GNT" : {
"address" : "0xE6de13D64F6036E4E3f5fC84B5EB620C5C7c1050"
}
}
}
85 changes: 85 additions & 0 deletions subgraph/src/deposits.template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import { Address, BigInt, BigDecimal } from '@graphprotocol/graph-ts';

import { Locked as LockedEvent, Unlocked as UnlockedEvent } from '../generated/Deposits/Deposits';
import { ERC20 } from '../generated/Deposits/ERC20';
import { Locked, Unlocked, LockedSummaryLatest, LockedSummarySnapshot } from '../generated/schema';

export function addLockedSummary<T>(event: T): void {
const burnAddress = Address.fromString('0x0000000000000000000000000000000000000000');

// Load GLM and GNT contracts
// eslint-disable-next-line no-template-curly-in-string
const glmContract = ERC20.bind(Address.fromString('${GLM_CONTRACT_ADDRESS}'));
// eslint-disable-next-line no-template-curly-in-string
const gntContract = ERC20.bind(Address.fromString('${GNT_CONTRACT_ADDRESS}'));
// Calculate current total supply
const glmSupply = glmContract.totalSupply().minus(glmContract.balanceOf(burnAddress));
const gntSupply = gntContract.totalSupply().minus(gntContract.balanceOf(burnAddress));
const totalSupply = glmSupply.plus(gntSupply);

// Load latest locked summary
let latestLockedSummary = LockedSummaryLatest.load('latest');
if (latestLockedSummary == null) {
latestLockedSummary = new LockedSummaryLatest('latest');
latestLockedSummary.lockedTotal = BigInt.fromI32(0);
latestLockedSummary.lockedRatio = BigDecimal.fromString('0');
}

// Calculate total locked and locked ratio
let lockedTotal: BigInt;
if (event instanceof LockedEvent) {
lockedTotal = latestLockedSummary.lockedTotal.plus(event.params.amount);
} else if (event instanceof UnlockedEvent) {
lockedTotal = latestLockedSummary.lockedTotal.minus(event.params.amount);
} else {
throw new Error('event must be of LockedEvent or UnlockEvent type');
}
const lockedRatio = lockedTotal.divDecimal(totalSupply.toBigDecimal());

// Save LockedSummaryLatest
latestLockedSummary.lockedTotal = lockedTotal;
latestLockedSummary.lockedRatio = lockedRatio;
latestLockedSummary.glmSupply = totalSupply;
latestLockedSummary.blockNumber = event.block.number.toI32();
latestLockedSummary.transactionHash = event.transaction.hash;
latestLockedSummary.timestamp = event.block.timestamp.toI32();
latestLockedSummary.save();

// Save LockedSummarySnapshot
const lockedSummarySnapshot = new LockedSummarySnapshot(
event.transaction.hash.concatI32(event.logIndex.toI32()),
);
lockedSummarySnapshot.lockedTotal = lockedTotal;
lockedSummarySnapshot.lockedRatio = lockedRatio;
lockedSummarySnapshot.glmSupply = totalSupply;
lockedSummarySnapshot.blockNumber = event.block.number.toI32();
lockedSummarySnapshot.transactionHash = event.transaction.hash;
lockedSummarySnapshot.timestamp = event.block.timestamp.toI32();
lockedSummarySnapshot.save();
}

export function handleLocked(event: LockedEvent): void {
const lockedEntity = new Locked(event.transaction.hash.concatI32(event.logIndex.toI32()));
lockedEntity.depositBefore = event.params.depositBefore;
lockedEntity.amount = event.params.amount;
lockedEntity.user = event.params.user;
lockedEntity.blockNumber = event.block.number.toI32();
lockedEntity.transactionHash = event.transaction.hash;
lockedEntity.timestamp = event.block.timestamp.toI32();
lockedEntity.save();

addLockedSummary(event);
}

export function handleUnlocked(event: UnlockedEvent): void {
const unlockedEntity = new Unlocked(event.transaction.hash.concatI32(event.logIndex.toI32()));
unlockedEntity.depositBefore = event.params.depositBefore;
unlockedEntity.amount = event.params.amount;
unlockedEntity.user = event.params.user;
unlockedEntity.blockNumber = event.block.number.toI32();
unlockedEntity.transactionHash = event.transaction.hash;
unlockedEntity.timestamp = event.block.timestamp.toI32();
unlockedEntity.save();

addLockedSummary(event);
}
6 changes: 4 additions & 2 deletions subgraph/src/deposits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ export function addLockedSummary<T>(event: T): void {
const burnAddress = Address.fromString('0x0000000000000000000000000000000000000000');

// Load GLM and GNT contracts
const glmContract = ERC20.bind(Address.fromString('0x71432DD1ae7DB41706ee6a22148446087BdD0906'));
const gntContract = ERC20.bind(Address.fromString('0xE6de13D64F6036E4E3f5fC84B5EB620C5C7c1050'));
// eslint-disable-next-line no-template-curly-in-string
const glmContract = ERC20.bind(Address.fromString('0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512'));
// eslint-disable-next-line no-template-curly-in-string
const gntContract = ERC20.bind(Address.fromString('0x5FbDB2315678afecb367f032d93F642f64180aa3'));
// Calculate current total supply
const glmSupply = glmContract.totalSupply().minus(glmContract.balanceOf(burnAddress));
const gntSupply = gntContract.totalSupply().minus(gntContract.balanceOf(burnAddress));
Expand Down
35 changes: 35 additions & 0 deletions subgraph/src/epochs.template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Address, ethereum, log, Bytes } from '@graphprotocol/graph-ts';

import { Epochs } from '../generated/Epochs/Epochs';
import { Epoch } from '../generated/schema';

export function handleBlock(block: ethereum.Block): void {
const epochsContract = Epochs.bind(
// eslint-disable-next-line no-template-curly-in-string
Address.fromString('${EPOCHS_CONTRACT_ADDRESS}'),
);
const currentEpoch = epochsContract.try_getCurrentEpoch();
if (currentEpoch.reverted) {
log.info('Call to getCurrentEpoch() reverted!', []);
return;
}

const epochNo = currentEpoch.value.toI32();
let epoch = Epoch.load(Bytes.fromI32(epochNo));
if (epoch == null) {
epoch = new Epoch(Bytes.fromI32(epochNo));

const decisionWindow = epochsContract.getDecisionWindow();
const duration = epochsContract.getEpochDuration();
const epochEnd = epochsContract.getCurrentEpochEnd();
const epochStart = epochEnd.minus(duration);

epoch.epoch = epochNo;
epoch.fromTs = epochStart;
epoch.toTs = epochEnd;
epoch.duration = duration;
epoch.decisionWindow = decisionWindow;

epoch.save();
}
}
3 changes: 2 additions & 1 deletion subgraph/src/epochs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { Epoch } from '../generated/schema';

export function handleBlock(block: ethereum.Block): void {
const epochsContract = Epochs.bind(
Address.fromString('0x86A032e5e5bEaaEB8eb0F625bEB5426D8B526719'),
// eslint-disable-next-line no-template-curly-in-string
Address.fromString('0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9'),
);
const currentEpoch = epochsContract.try_getCurrentEpoch();
if (currentEpoch.reverted) {
Expand Down
17 changes: 17 additions & 0 deletions subgraph/src/vault.template.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Withdrawal } from '../generated/schema';
import { Withdrawn } from '../generated/Vault/Vault';

export function handleWithdrawn(event: Withdrawn): void {
const id = event.transaction.hash.concatI32(event.logIndex.toI32());
const entity = new Withdrawal(id);

entity.amount = event.params.amount;
entity.user = event.params.user;
entity.epoch = event.params.epoch.toI32();

entity.blockNumber = event.block.number.toI32();
entity.transactionHash = event.transaction.hash;
entity.timestamp = event.block.timestamp.toI32();

entity.save();
}

0 comments on commit bfda4a0

Please sign in to comment.