I'm currently playing around with Proxy Upgradability, and noticed the use of assembly in terms of the new upgraded contract and the slot assigned. Real implementation can be seen here.
I have broken this implementation down to understand what is happening:
pragma solidity ^0.5.0;
contract Base {
bytes32 internal constant IMPLEMENTATION_SLOT = 0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3;
function _setImplementation(address newImplementation) public {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
sstore(slot, newImplementation)
}
}
function _implementation() public view returns (address impl) {
bytes32 slot = IMPLEMENTATION_SLOT;
assembly {
impl := sload(slot)
}
}
function getSlot() public view returns(bytes32) {
return IMPLEMENTATION_SLOT;
}
}
Then created tests to see the results, and see what is modified etc...
const Base = artifacts.require("Base")
contract('Base', function(account) {
beforeEach(async function () {
this.base = await Base.new();
})
describe('...', function () {
describe('...', function () {
it('check slot', async function () {
console.log(await this.base.getSlot());
})
it('check slot', async function () {
console.log(await this.base._implementation());
})
it('change slot', async function () {
console.log(account[0]);
await this.base._setImplementation(account[0]);
})
it('check slot', async function () {
console.log(await this.base.getSlot());
})
it('check slot', async function () {
console.log(await this.base._implementation());
})
})
})
})
Which gives the result:
0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3
✓ check slot
0x0000000000000000000000000000000000000000
✓ check slot
0x627306090abaB3A6e1400e9345bC60c78a8BEf57
✓ change slot (69ms)
0x7050c9e0f4ca769c69bd3a8ef740bc37934f8e2c036e5a723fd8ee048ed3f8c3
✓ check slot
0x0000000000000000000000000000000000000000
✓ check slot
Why does the slot variable not change, and if that is not meant to change, why does ADMIN_SLOT not change either?
slot
with the value of the constantIMPLEMENTATION_SLOT
, and then writing a different value intoslot
(whether you do it in assembly or not), would change the value of the constantIMPLEMENTATION_SLOT
??? The variableslot
does not reference the variableIMPLEMENTATION_SLOT
as a result ofslot = IMPLEMENTATION_SLOT
! And in any case, did you actually expect to be able to change the value of a constant in the contract? Why o you think it's called "constant"? – goodvibration Jul 15 '19 at 20:04