Skip to content

Commit 99d4437

Browse files
stuartwkaggre
andauthored
use clone in property factory (#408)
* use clone in property factory * adds initializeProperty * moves initial property into registry * sets property in registry * create initial property and set in registry * generates property before all generate factory instances * generate property inside property factory tests * changes way property contract is deployed before factory * add deployment script * update deployment script --------- Co-authored-by: aggre <hiroyuki.aggre@gmail.com>
1 parent 4eeec34 commit 99d4437

File tree

6 files changed

+91
-14
lines changed

6 files changed

+91
-14
lines changed

.vscode/settings.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,6 @@
1212
],
1313
"editor.codeActionsOnSave": {
1414
"source.fixAll.eslint": true
15-
}
15+
},
16+
"solidity.compileUsingRemoteVersion": "v0.8.9+commit.e5eed63a"
1617
}

contracts/src/property/Property.sol

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
11
// SPDX-License-Identifier: MPL-2.0
22
pragma solidity =0.8.9;
33

4+
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
45
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
56
import "@openzeppelin/contracts/utils/structs/EnumerableSet.sol";
67
import "../../interface/IWithdraw.sol";
78
import "../../interface/IProperty.sol";
89
import "../../interface/IPropertyFactory.sol";
910
import "../../interface/IPolicy.sol";
10-
import "../common/registry/UsingRegistry.sol";
11+
import "../common/registry/InitializableUsingRegistry.sol";
1112

1213
/**
1314
* A contract that represents the assets of the user and collects staking from the stakers.
1415
* Property contract inherits ERC20.
1516
* Holders of Property contracts(tokens) receive holder rewards according to their share.
1617
*/
17-
contract Property is ERC20, UsingRegistry, IProperty {
18+
contract Property is ERC20Upgradeable, InitializableUsingRegistry, IProperty {
1819
uint8 private constant PROPERTY_DECIMALS = 18;
1920
uint8 private __decimals;
2021
uint256 private constant SUPPLY = 10000000000000000000000000;
@@ -32,12 +33,15 @@ contract Property is ERC20, UsingRegistry, IProperty {
3233
* @param _name The name of the new Property.
3334
* @param _symbol The symbol of the new Property.
3435
*/
35-
constructor(
36+
function initialize(
3637
address _registry,
3738
address _own,
3839
string memory _name,
3940
string memory _symbol
40-
) ERC20(_name, _symbol) UsingRegistry(_registry) {
41+
) public initializer {
42+
__ERC20_init(_name, _symbol);
43+
__UsingRegistry_init(_registry);
44+
4145
/**
4246
* Validates the sender is PropertyFactory contract.
4347
*/

contracts/src/property/PropertyFactory.sol

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import "../../interface/IPropertyFactory.sol";
66
import "../../interface/IMarket.sol";
77
import "../common/registry/InitializableUsingRegistry.sol";
88
import "./Property.sol";
9+
import "@openzeppelin/contracts/proxy/Clones.sol";
910

1011
/**
1112
* A factory contract that creates a new Property contract.
@@ -77,13 +78,13 @@ contract PropertyFactory is InitializableUsingRegistry, IPropertyFactory {
7778
/**
7879
* Creates a new Property contract.
7980
*/
80-
Property _property = new Property(
81+
address propertyAddr = Clones.clone(registry().registries("Property"));
82+
Property(propertyAddr).initialize(
8183
address(registry()),
8284
_author,
8385
_name,
8486
_symbol
8587
);
86-
address propertyAddr = address(_property);
8788

8889
/**
8990
* Adds the new Property contract to the Property address set.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { upgradeProxy, validateUpgrade } from '@openzeppelin/truffle-upgrades'
2+
import { type ContractClass } from '@openzeppelin/truffle-upgrades/dist/utils'
3+
4+
const PropertyFactory = artifacts.require('PropertyFactory')
5+
const AddressRegistry = artifacts.require('AddressRegistry')
6+
7+
const handler = async function (_, network) {
8+
if (network === 'test') {
9+
return
10+
}
11+
12+
const proxyAddress = process.env.PROPERTY_FACTORY_PROXY!
13+
const proxyAddressAddressRegistry = process.env.ADDRESS_REGISTRY_PROXY!
14+
15+
const newProperty = artifacts.require('Property')
16+
_.deploy(newProperty)
17+
const deployedNewProperty = await newProperty.deployed()
18+
console.log(`[CONFIRMED] new seed Property: ${deployedNewProperty.address}`)
19+
20+
const existingAddressRegistry = await AddressRegistry.deployed().catch(() =>
21+
AddressRegistry.at(proxyAddressAddressRegistry)
22+
)
23+
24+
await existingAddressRegistry.setRegistry(
25+
'Property',
26+
deployedNewProperty.address
27+
)
28+
console.log('[CONFIRMED] set the seed Property to Registry')
29+
30+
const existing = await PropertyFactory.deployed().catch(() =>
31+
PropertyFactory.at(proxyAddress)
32+
)
33+
34+
console.log('proxy:', existing.address)
35+
36+
await validateUpgrade(
37+
existing.address,
38+
PropertyFactory as unknown as ContractClass
39+
)
40+
41+
console.log('New implementation is valid')
42+
43+
await upgradeProxy(
44+
existing.address,
45+
PropertyFactory as unknown as ContractClass
46+
)
47+
} as Truffle.Migration
48+
49+
export = handler

test/property/property.ts

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -130,19 +130,23 @@ contract(
130130

131131
describe('Property; constructor', () => {
132132
it('Cannot be created from other than factory', async () => {
133-
const result = await propertyContract
134-
.new(dev.addressRegistry.address, author, 'sample', 'SAMPLE', {
133+
const propertyInstance = await propertyContract.new()
134+
135+
const result = await propertyInstance
136+
.initialize(dev.addressRegistry.address, author, 'sample', 'SAMPLE', {
135137
from: deployer,
136138
})
137139
.catch((err: Error) => err)
140+
138141
validateAddressErrorMessage(result)
139142
})
140143
it('The author, decimal places, and number of issues are fixed values', async () => {
141144
await dev.addressRegistry.setRegistry(
142145
'PropertyFactory',
143146
propertyFactory
144147
)
145-
const propertyInstance = await propertyContract.new(
148+
const propertyInstance = await propertyContract.new()
149+
await propertyInstance.initialize(
146150
dev.addressRegistry.address,
147151
author,
148152
'sample',
@@ -179,7 +183,8 @@ contract(
179183
'PropertyFactory',
180184
propertyFactory
181185
)
182-
const propertyInstance = await propertyContract.new(
186+
const propertyInstance = await propertyContract.new()
187+
await propertyInstance.initialize(
183188
dev.addressRegistry.address,
184189
author,
185190
'sample',
@@ -214,7 +219,8 @@ contract(
214219
'PropertyFactory',
215220
propertyFactory
216221
)
217-
const propertyInstance = await propertyContract.new(
222+
const propertyInstance = await propertyContract.new()
223+
await propertyInstance.initialize(
218224
dev.addressRegistry.address,
219225
author,
220226
'sample',
@@ -238,7 +244,8 @@ contract(
238244
'PropertyFactory',
239245
propertyFactory
240246
)
241-
const propertyInstance = await propertyContract.new(
247+
const propertyInstance = await propertyContract.new()
248+
await propertyInstance.initialize(
242249
dev.addressRegistry.address,
243250
author,
244251
'sample',
@@ -273,7 +280,8 @@ contract(
273280
'PropertyFactory',
274281
propertyFactory
275282
)
276-
const propertyInstance = await propertyContract.new(
283+
const propertyInstance = await propertyContract.new()
284+
await propertyInstance.initialize(
277285
dev.addressRegistry.address,
278286
author,
279287
'sample',

test/test-lib/instance.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import type {
1919
ArbSysTestInstance,
2020
DevPolygonInstance,
2121
TokenURIDescriptorTestInstance,
22+
PropertyInstance,
2223
TokenURIDescriptorCopyTestInstance,
2324
TokenURIDescriptorLegacyTestInstance,
2425
} from '../../types/truffle-contracts'
@@ -248,7 +249,20 @@ export class DevProtocolInstance {
248249
)
249250
}
250251

252+
public async generateProperty(): Promise<void> {
253+
const Property = contract('Property')
254+
const property = await Property.new(this.fromDeployer)
255+
256+
await this.addressRegistry.setRegistry(
257+
'Property',
258+
property.address,
259+
this.fromDeployer
260+
)
261+
}
262+
251263
public async generatePropertyFactory(): Promise<void> {
264+
await this.generateProperty()
265+
252266
const [proxfied] = await deployProxy(
253267
contract('PropertyFactory'),
254268
this._deployer

0 commit comments

Comments
 (0)