Skip to content

Commit 3aaabd6

Browse files
feat: updated Solidity interface policy
Introduces a new proposal to update the Solidity interface policy such that source contracts do not use interfaces at all and interfaces live in an entirely separate folder. Proposal is intended to set us up to fully automate interface generation while still maintaining most of the compilation benefits.
1 parent 78c8568 commit 3aaabd6

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed

solidity/solidity-interfaces.md

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Updated Solidity Interface Policy
2+
3+
## Context
4+
5+
Smart contract interfaces are useful tools that allow external tools, contracts, and tests to
6+
interact with smart contracts using their ABIs instead of interacting with the underlying
7+
implementation contract. Interfaces are generally more flexible than implementations because we
8+
pin implementations to specific compiler versions whereas interfaces can have carat versions that
9+
cover an entire Solidity major version.
10+
11+
Interfaces are also valuable because they create a separation between source contracts and other
12+
contracts that need to interact with those source contracts. This separation significantly
13+
decreases compilation time when changes need to be made to source contracts. Any changes to a
14+
source contract would otherwise trigger a re-compilation of many other contracts that rely on that
15+
source contract, resulting in untolerably long waits.
16+
17+
## Problem Statement
18+
19+
We recently undertook an update to the Optimism Monorepo that added interfaces for all smart
20+
contracts. This resulted in a significant improvement to compilation time but simultaneously added
21+
complexity for any developer that needs to introduce a new smart contract. Most of this complexity
22+
arises because existing interface policy is non-obvious and the process for generating interfaces
23+
is entirely manual. We would like to make certain changes to this policy to support a better
24+
development process.
25+
26+
We wanted to entirely automate the interface generation process so that users do not need to
27+
generate interfaces themselves. In exploratory work on this interface generation process, we've
28+
found that there are a number of important edge cases that came up.
29+
30+
Specifically:
31+
32+
- Source contracts using interfaces creates a basic dependency problem. For instance, suppose that
33+
you'd like to add a new contract `ContractA`. You'd also like to create a new contract
34+
`ContractB` that depends on `ContractA`. Our current policy states that `ContractB` should use
35+
the interface for `ContractA`, `IContractA`. You would therefore need to generate the interface
36+
for `ContractA` *before* starting to work on `ContractB`, which is annoying.
37+
- Circular dependencies in source contracts are basically impossible to resolve without manually
38+
crafting contract interfaces. For instance, if `ContractA` depends on `IContractB` and
39+
`ContractB` depends on `IContractA` but neither contract interface exists yet (new contracts)
40+
then the contracts cannot be compiled (because neither interface exists) and the interfaces can
41+
not be generated. Catch 22.
42+
- Using interfaces within the source contracts leads to other awkward situations with function
43+
types that are challenging to resolve in an automated generation script.
44+
- Contract interfaces don't have source code, so navigating the functions in the source files
45+
becomes awkward as each external call goes through an interface.
46+
47+
## Proposed Solution
48+
49+
All of the above seem to point to a change to our policy where contract interfaces are not used
50+
*anywhere* in the source contracts and are only used in tests or other external/peripheral
51+
locations that interact with the source contracts. Removing interfaces from source contracts
52+
entirely would also be a much clearer mental model ("just don't use interfaces in src/").
53+
54+
In addition, interfaces would live in a new `interfaces` folder at the root of the contracts
55+
package that has a structure that identically mirrors the `src` folder. As with the other changes,
56+
this is meant to support automation and clearly separate interfaces from source contracts.
57+
58+
## Considerations
59+
60+
### Compilation Time
61+
62+
Proposed solution would increase compilation time for source contracts, but the impact would not be
63+
nearly as significant as the original compilation time when no interfaces existed at all. We're
64+
talking about something on the order of 5-20s instead of the current 2-10s. Not ideal but fine.
65+
66+
### Interface Usage
67+
68+
Developers must first generate contract interfaces before they can be used by things like tests or
69+
scripts. Not a change from the status quo since this is already the case today.
70+
71+
### Continued Automation Challenges
72+
73+
Simply removing interface usage will solve the problems that come with using interfaces within the
74+
source contracts but will not solve all of the challenges to automating interface generation. We do
75+
have some concrete improvements like limiting complexity that comes with things like typecasting to
76+
testing/peripheral code only and not source code.
77+
78+
### Future Proofing
79+
80+
More recent versions of Solidity are beginning to optimize for usecases like ours where the same
81+
contracts are being used in many different places. It's possible that we will eventually not need
82+
interfaces anywhere in the internal codebase to still maintain a solid compilation time. We don't
83+
expect this to be true for at least another 6-12 months but it's something to consider. Making a
84+
change like this now at least limits the impact of a more sweeping interface-removal change later.

0 commit comments

Comments
 (0)