Track inherited contracts using exported symbols

pull/2609/head
David Disu 2 years ago committed by Aniket
parent e7968c7211
commit b522b2a853
  1. 34
      libs/remix-core-plugin/src/lib/openzeppelin-proxy.ts
  2. 185
      libs/remix-core-plugin/src/types/contract.ts
  3. 5
      libs/remix-ui/run-tab/src/lib/actions/events.ts

@ -1,6 +1,6 @@
import { Plugin } from '@remixproject/engine';
import { ContractABI, ContractAST, DeployOptions } from '../types/contract';
import { UUPS, UUPSABI, UUPSBytecode, UUPSfunAbi, UUPSupgradeAbi } from './constants/uups';
import { Plugin } from '@remixproject/engine'
import { ContractABI, ContractAST, ContractSources, DeployOptions } from '../types/contract'
import { UUPS, UUPSABI, UUPSBytecode, UUPSfunAbi, UUPSupgradeAbi } from './constants/uups'
const proxyProfile = {
name: 'openzeppelin-proxy',
@ -28,20 +28,30 @@ export class OpenZeppelinProxy extends Plugin {
return false
}
async getProxyOptions (contracts: ContractABI): Promise<{ [name: string]: DeployOptions }> {
async getProxyOptions (data: ContractSources, file: string): Promise<{ [name: string]: DeployOptions }> {
const contracts = data.contracts[file]
const ast = data.sources[file].ast
const inputs = {}
if (this.kind === 'UUPS') {
Object.keys(contracts).map(name => {
const abi = contracts[name].abi
const initializeInput = abi.find(node => node.name === 'initialize')
if (ast) {
const UUPSSymbol = ast.exportedSymbols['UUPSUpgradeable'] ? ast.exportedSymbols['UUPSUpgradeable'][0] : null
inputs[name] = {
options: [{ title: 'Deploy with Proxy', active: false }, { title: 'Upgrade with Proxy', active: false }],
initializeOptions: {
inputs: initializeInput,
initializeInputs: initializeInput ? this.blockchain.getInputs(initializeInput) : null
}
ast.absolutePath === file && ast.nodes.map((node) => {
if (node.name === name && node.linearizedBaseContracts.includes(UUPSSymbol)) {
const abi = contracts[name].abi
const initializeInput = abi.find(node => node.name === 'initialize')
inputs[name] = {
options: [{ title: 'Deploy with Proxy', active: false }, { title: 'Upgrade with Proxy', active: false }],
initializeOptions: {
inputs: initializeInput,
initializeInputs: initializeInput ? this.blockchain.getInputs(initializeInput) : null
}
}
}
})
}
})
}

@ -54,86 +54,40 @@ export interface ContractAST {
}[]
}
export interface ContractABI {
[key: string]: {
abi: ({
inputs: never[];
stateMutability: string;
type: string;
anonymous?: undefined;
name?: undefined;
outputs?: undefined;
} | {
anonymous: boolean;
inputs: {
indexed: boolean;
internalType: string;
name: string;
type: string;
}[];
name: string;
type: string;
stateMutability?: undefined;
outputs?: undefined;
} | {
inputs: {
internalType: string;
name: string;
type: string;
}[];
name: string;
outputs: {
internalType: string;
name: string;
type: string;
}[];
stateMutability: string;
type: string;
anonymous?: undefined;
})[];
devdoc: {
kind: string;
methods: {
[key: string]: {
[key: string]: string
}
};
version: number;
};
evm: any
metadata: string;
storageLayout: {
storage: {
astId: number;
contract: string;
label: string;
offset: number;
slot: string;
type: string;
}[];
types: {
[key: string]: {
base: string;
encoding: string;
label: string;
numberOfBytes: string;
members?: {
astId: number;
contract: string;
label: string;
offset: number;
slot: string;
type: string;
}[];
};
};
};
userdoc: {
kind: string;
methods: any;
version: number;
};
};
export type ContractABI = {
inputs: [];
stateMutability: string;
type: string;
anonymous?: undefined;
name?: string;
outputs?: undefined;
} | {
anonymous: boolean;
inputs: {
indexed: boolean;
internalType: string;
name: string;
type: string;
}[];
name: string;
type: string;
stateMutability?: undefined;
outputs?: undefined;
} | {
inputs: {
internalType: string;
name: string;
type: string;
}[];
name: string;
outputs: {
internalType: string;
name: string;
type: string;
}[];
stateMutability: string;
type: string;
anonymous?: undefined;
}
export type DeployMode = 'Deploy with Proxy' | 'Upgrade with Proxy'
@ -158,3 +112,74 @@ export interface DeployOptions {
initializeOptions: DeployOption,
options: { title: DeployMode, active: boolean }[]
}
export interface ContractSources {
contracts: {
[path: string]: {
[contractName: string]: {
abi: ContractABI[],
devdoc: {
kind: string
methods: {
[key: string]: {
[key: string]: string
}
};
version: number
}
evm: any
metadata: string
storageLayout: {
storage: {
astId: number
contract: string
label: string
offset: number
slot: string
type: string
}[]
types: {
[key: string]: {
base: string
encoding: string
label: string
numberOfBytes: string
members?: {
astId: number
contract: string
label: string
offset: number
slot: string
type: string
}[]
}
}
}
userdoc: {
kind: string
methods: any
version: number
}
}
}
},
error: {
component: string,
errorCode: string,
formattedMessage: string,
message: string,
severity: string,
sourceLocation: {
end: number,
file: string,
start: number
},
type: string
}[],
sources: {
[path: string]: {
ast: ContractAST,
id: number
}
}
}

@ -6,6 +6,7 @@ import { addDeployOption, clearAllInstances, clearRecorderCount, fetchContractLi
import { CompilerAbstract } from '@remix-project/remix-solidity'
import * as ethJSUtil from 'ethereumjs-util'
import Web3 from 'web3'
import { ContractSources } from "../types"
export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
plugin.blockchain.events.on('newTransaction', (tx, receipt) => {
@ -92,7 +93,7 @@ export const setupEvents = (plugin: RunTab, dispatch: React.Dispatch<any>) => {
})
}
const broadcastCompilationResult = async (plugin: RunTab, dispatch: React.Dispatch<any>, file, source, languageVersion, data, input?) => {
const broadcastCompilationResult = async (plugin: RunTab, dispatch: React.Dispatch<any>, file, source, languageVersion, data: ContractSources, input?) => {
// TODO check whether the tab is configured
const compiler = new CompilerAbstract(languageVersion, data, source, input)
@ -108,7 +109,7 @@ const broadcastCompilationResult = async (plugin: RunTab, dispatch: React.Dispat
const isUpgradeable = await plugin.call('openzeppelin-proxy', 'isConcerned', data.sources[file] ? data.sources[file].ast : {})
if (isUpgradeable) {
const options = await plugin.call('openzeppelin-proxy', 'getProxyOptions', data.contracts[file])
const options = await plugin.call('openzeppelin-proxy', 'getProxyOptions', data, file)
dispatch(addDeployOption({ [file]: options }))
} else {

Loading…
Cancel
Save