# Why the same ERC1967Upgrade.sol contract is needed both in proxy and implementation contracts?

**URL:** <https://forum.openzeppelin.com/t/why-the-same-erc1967upgrade-sol-contract-is-needed-both-in-proxy-and-implementation-contracts/28133>\
**Category:** Upgrades\
**Tags:** proxies, upgrades\
**Created:** [April 28, 2022, 12:48pm UTC](https://forum.openzeppelin.com/t/why-the-same-erc1967upgrade-sol-contract-is-needed-both-in-proxy-and-implementation-contracts/28133 "2022-04-28T12:48:57Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![takeshi.reg](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/takeshi.reg/32/14647_2.png) [@takeshi.reg](https://forum.openzeppelin.com/u/takeshi.reg)\
**Post date:** [April 28, 2022, 12:48pm UTC](https://forum.openzeppelin.com/t/why-the-same-erc1967upgrade-sol-contract-is-needed-both-in-proxy-and-implementation-contracts/28133/1 "2022-04-28T12:48:57Z")

</div>

I’m curious why both [ERC1967Proxy](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/proxy/ERC1967/ERC1967Proxy.sol) (UUPS proxy) and [UUPSUpgradeable.sol](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/proxy/utils/UUPSUpgradeable.sol) (implementation side lib) contracts have the same dependency - ERC1967Upgrade.sol

My best guess is that the ERC1967Upgrade.sol logic is needed only at proxy creation time and the reason to use the same lib is to make sure that storage slots are not not mixed up. Is it so? Is there another motivation?

---

<div class="post-metadata">

**Author:** ![ericglau](https://sea2.discourse-cdn.com/flex022/user_avatar/forum.openzeppelin.com/ericglau/32/15149_2.png) [@ericglau](https://forum.openzeppelin.com/u/ericglau)\
**Post date:** [April 28, 2022, 9:32pm UTC](https://forum.openzeppelin.com/t/why-the-same-erc1967upgrade-sol-contract-is-needed-both-in-proxy-and-implementation-contracts/28133/2 "2022-04-28T21:32:56Z")

</div>

[`ERC1967Upgrade`](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/proxy/ERC1967/ERC1967Upgrade.sol) provides functions to deal with EIP1967 storage slots, so it is used both in the proxy (e.g. during [creation](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/proxy/ERC1967/ERC1967Proxy.sol#L24) as you mentioned) and also in the UUPS implementation (e.g. during [upgrade](https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v4.6.0/contracts/proxy/utils/UUPSUpgradeable.sol#L66) which is called through the proxy with `delegatecall`).
