Repository: vyperlang/vyper

Issue:
`create_with_code_of()` name is somewhat misleading
### What's your issue about?

I was not familiar with the inner workings of the Vyper compiler before diving deep into the Uniswap codebase.
While inspecting their contracts I always assumed that `create_with_code_of()` would `CODECOPY` the whole code of the target contract but, once I dug into Vyper and much to my big surprise, it creates a forwarder (which makes a lot of sense reusability-wise).

### How can it be fixed?

Like I was fooled I believe that others might be and I would propose a more expressive name for this (given its name is already long), something along the lines of: `create_forwarder_to` or `create_delegated_copy_of`

#### Cute Animal Picture

![](http://i.imgur.com/NoIi9ol.jpg)



Discussion:
That is a great point! We should discuss at our meeting on Monday
Agreed, I think we should think of something clearer. `create_delegated_copy_of` and `create_forwarder` are good candidates.
Approved not decided on the right name yet, other suggested names:
`create_proxy`
`create_instance_of`

@charles-cooper @fubuloubu I am keen on getting this fixed. I think the term _forwarder_ best describes the behaviour, as proxies is quite a broad IT term. Can I go ahead with `create_forwarder_to` ?
SGTM
Cool, I will pick this one up next - is simple enough hehe ;)

Resolving patch:
diff --git a/vyper/functions/functions.py b/vyper/functions/functions.py
--- a/vyper/functions/functions.py
+++ b/vyper/functions/functions.py
@@ -1007,7 +1007,7 @@ def shift(expr, args, kwargs, context):
     )
 
 
-def get_create_with_code_of_bytecode():
+def get_create_forwarder_to_bytecode():
     from vyper.compile_lll import (
         assembly_to_evm,
         num_to_bytearray
@@ -1047,7 +1047,7 @@ def get_create_with_code_of_bytecode():
 
 
 @signature('address', value=Optional('uint256', zero_value))
-def create_with_code_of(expr, args, kwargs, context):
+def create_forwarder_to(expr, args, kwargs, context):
 
     value = kwargs['value']
     if value != zero_value:
@@ -1060,7 +1060,7 @@ def create_with_code_of(expr, args, kwargs, context):
         )
     placeholder = context.new_placeholder(ByteArrayType(96))
 
-    kode = get_create_with_code_of_bytecode()
+    kode = get_create_forwarder_to_bytecode()
     high = bytes_to_int(kode[:32])
     low = bytes_to_int((kode + b'\x00' * 32)[47:79])
 
@@ -1159,7 +1159,7 @@ def _clear():
     'uint256_addmod': uint256_addmod,
     'uint256_mulmod': uint256_mulmod,
     'shift': shift,
-    'create_with_code_of': create_with_code_of,
+    'create_forwarder_to': create_forwarder_to,
     'min': _min,
     'max': _max,
 }
@@ -1170,5 +1170,5 @@ def _clear():
     'selfdestruct': selfdestruct,
     'raw_call': raw_call,
     'raw_log': raw_log,
-    'create_with_code_of': create_with_code_of,
+    'create_forwarder_to': create_forwarder_to,
 }


Test patch:
diff --git a/tests/parser/exceptions/test_constancy_exception.py b/tests/parser/exceptions/test_constancy_exception.py
--- a/tests/parser/exceptions/test_constancy_exception.py
+++ b/tests/parser/exceptions/test_constancy_exception.py
@@ -45,7 +45,7 @@ def foo() -> int128:
 @public
 @constant
 def foo() -> int128:
-    x = create_with_code_of(0x1234567890123456789012345678901234567890, value=9)
+    x = create_forwarder_to(0x1234567890123456789012345678901234567890, value=9)
     return 5
     """,
     """
diff --git a/tests/parser/exceptions/test_invalid_literal_exception.py b/tests/parser/exceptions/test_invalid_literal_exception.py
--- a/tests/parser/exceptions/test_invalid_literal_exception.py
+++ b/tests/parser/exceptions/test_invalid_literal_exception.py
@@ -55,7 +55,7 @@ def foo():
     """
 @public
 def foo():
-    x = create_with_code_of(0x123456789012345678901234567890123456789)
+    x = create_forwarder_to(0x123456789012345678901234567890123456789)
     """,
     """
 @public
diff --git a/tests/parser/exceptions/test_structure_exception.py b/tests/parser/exceptions/test_structure_exception.py
--- a/tests/parser/exceptions/test_structure_exception.py
+++ b/tests/parser/exceptions/test_structure_exception.py
@@ -98,7 +98,7 @@ def foo():
     """
 @public
 def foo():
-    x = create_with_code_of(0x1234567890123456789012345678901234567890, b"cow")
+    x = create_forwarder_to(0x1234567890123456789012345678901234567890, b"cow")
     """,
     """
 @public
@@ -108,7 +108,7 @@ def foo():
     """
 @public
 def foo():
-    x = create_with_code_of(0x1234567890123456789012345678901234567890, outsize=4)
+    x = create_forwarder_to(0x1234567890123456789012345678901234567890, outsize=4)
     """,
     """
 x: public()
diff --git a/tests/parser/features/test_assert.py b/tests/parser/features/test_assert.py
--- a/tests/parser/features/test_assert.py
+++ b/tests/parser/features/test_assert.py
@@ -121,7 +121,7 @@ def test():
     code = """
 @public
 def test():
-    assert create_with_code_of(self) == 1
+    assert create_forwarder_to(self) == 1
     """
     assert_compile_failed(lambda: get_contract(code), ConstancyViolationException)
 
diff --git a/tests/parser/functions/test_create_with_code_of.py b/tests/parser/functions/test_create_with_code_of.py
--- a/tests/parser/functions/test_create_with_code_of.py
+++ b/tests/parser/functions/test_create_with_code_of.py
@@ -1,12 +1,12 @@
 
 
-def test_create_with_code_of_create(get_contract):
+def test_create_forwarder_to_create(get_contract):
     code = """
 main: address
 
 @public
 def test() -> address:
-    self.main = create_with_code_of(self)
+    self.main = create_forwarder_to(self)
     return self.main
     """
 
@@ -15,7 +15,7 @@ def test() -> address:
     assert c.test() == '0x4F9DA333DCf4E5A53772791B95c161B2FC041859'
 
 
-def test_create_with_code_of_call(get_contract, w3):
+def test_create_forwarder_to_call(get_contract, w3):
     code = """
 
 contract SubContract:
@@ -28,7 +28,7 @@ def hello() -> bytes[100]: constant
 
 @public
 def test() -> address:
-    self.other = create_with_code_of(self)
+    self.other = create_forwarder_to(self)
     return self.other
 
 
@@ -63,7 +63,7 @@ def hello(a: uint256) -> bytes[100]: constant
 
 @public
 def test() -> address:
-    self.other = create_with_code_of(self)
+    self.other = create_forwarder_to(self)
     return self.other
 
 
diff --git a/tests/parser/functions/test_raw_call.py b/tests/parser/functions/test_raw_call.py
--- a/tests/parser/functions/test_raw_call.py
+++ b/tests/parser/functions/test_raw_call.py
@@ -1,4 +1,4 @@
-from vyper.functions import get_create_with_code_of_bytecode
+from vyper.functions import get_create_forwarder_to_bytecode
 
 
 def test_caller_code(get_contract_with_gas_estimation):
@@ -36,13 +36,13 @@ def returnten() -> int128:
     outer_code = """
 @public
 def create_and_call_returnten(inp: address) -> int128:
-    x: address = create_with_code_of(inp)
+    x: address = create_forwarder_to(inp)
     o: int128 = extract32(raw_call(x, convert("\xd0\x1f\xb1\xb8", bytes[4]), outsize=32, gas=50000), 0, type=int128)  # noqa: E501
     return o
 
 @public
 def create_and_return_forwarder(inp: address) -> address:
-    x: address = create_with_code_of(inp)
+    x: address = create_forwarder_to(inp)
     return x
     """
 
@@ -50,7 +50,7 @@ def create_and_return_forwarder(inp: address) -> address:
     assert c2.create_and_call_returnten(c.address) == 10
     c2.create_and_call_returnten(c.address, transact={})
 
-    expected_forwarder_code_mask = get_create_with_code_of_bytecode()[12:]
+    expected_forwarder_code_mask = get_create_forwarder_to_bytecode()[12:]
 
     c3 = c2.create_and_return_forwarder(c.address, call={})
     c2.create_and_return_forwarder(c.address, transact={})
@@ -78,13 +78,13 @@ def returnten() -> int128:
     outer_code = """
 @public
 def create_and_call_returnten(inp: address) -> int128:
-    x: address = create_with_code_of(inp)
+    x: address = create_forwarder_to(inp)
     o: int128 = extract32(raw_call(x, convert("\xd0\x1f\xb1\xb8", bytes[4]), outsize=32, gas=50000), 0, type=int128)  # noqa: E501
     return o
 
 @public
 def create_and_return_forwarder(inp: address) -> address:
-    return create_with_code_of(inp)
+    return create_forwarder_to(inp)
     """
 
     c2 = get_contract_with_gas_estimation(outer_code)
diff --git a/tests/parser/syntax/test_block.py b/tests/parser/syntax/test_block.py
--- a/tests/parser/syntax/test_block.py
+++ b/tests/parser/syntax/test_block.py
@@ -9,7 +9,7 @@
     """
 @public
 def foo() -> int128:
-    x: address = create_with_code_of(
+    x: address = create_forwarder_to(
         0x1234567890123456789012345678901234567890,
         value=block.timestamp,
     )
diff --git a/tests/parser/syntax/test_create_with_code_of.py b/tests/parser/syntax/test_create_with_code_of.py
--- a/tests/parser/syntax/test_create_with_code_of.py
+++ b/tests/parser/syntax/test_create_with_code_of.py
@@ -8,7 +8,7 @@
     """
 @public
 def foo():
-    x: address = create_with_code_of(0x1234567890123456789012345678901234567890, value=4, value=9)
+    x: address = create_forwarder_to(0x1234567890123456789012345678901234567890, value=4, value=9)
     """
 ]
 
@@ -23,12 +23,12 @@ def test_type_mismatch_exception(bad_code):
     """
 @public
 def foo():
-    x: address = create_with_code_of(0x1234567890123456789012345678901234567890)
+    x: address = create_forwarder_to(0x1234567890123456789012345678901234567890)
     """,
     """
 @public
 def foo():
-    x: address = create_with_code_of(
+    x: address = create_forwarder_to(
         0x1234567890123456789012345678901234567890,
         value=as_wei_value(9, "wei")
     )
@@ -36,7 +36,7 @@ def foo():
     """
 @public
 def foo():
-    x: address = create_with_code_of(0x1234567890123456789012345678901234567890, value=9)
+    x: address = create_forwarder_to(0x1234567890123456789012345678901234567890, value=9)
     """
 ]